Re: [xsl] Unable to get text() of node

Subject: Re: [xsl] Unable to get text() of node
From: Kasimier Buchcik <K.Buchcik@xxxxxxxxxxxx>
Date: Mon, 23 Jan 2006 12:38:31 +0100
Hi,

I tried to summerize this issue for the benefit of my own
understanding, and would be glad to be corrected if something's
wrong. Mainly I did this because I wanted to test if
Libxslt (1.1.15) works the same way as Saxon (6.5.5) here.

Selection of text-nodes
=======================

Stylesheet
------------
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";> [^]
  <xsl:template match="/"> 
    <output><xsl:apply-templates select="foo"/></output>
  </xsl:template>

  <xsl:template match="foo">
    <xsl:text>"</xsl:text><xsl:value-of
select="text()"/><xsl:text>"</xsl:text>
  </xsl:template>
</xsl:stylesheet>

Instance
----------
<?xml version="1.0"?>
<foo>Johnny
    <bar>don't</bar>
    B.
    <bar/>Good
</foo>

The output will be:

<output>"Johnny
    "</output>

So only the first text node is processed.
On the other hand, changing the stylesheet to use a
<xsl:copy-of select="text()"/> (note "copy-of") will output the text
of _all_ selected text-nodes:

<output>"Johnny

    B.
    Good
"</output>

A <xsl:copy-of select="."/> will select the concatenated text of all
descendant text-nodes in document-order; note the additional "don't" in
the result:

<output>"Johnny
    don't
    B.
    Good
"</output>

Handling of whitespace
======================

Stylesheet
------------
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";> [^]

  <xsl:template match="/"> 
    <output><xsl:apply-templates select="foo"/></output>
  </xsl:template>

  <xsl:template match="foo">
    <xsl:text>"</xsl:text><xsl:value-of
select="."/><xsl:text>"</xsl:text>
  </xsl:template>
</xsl:stylesheet>

Instance
----------
<?xml version="1.0"?>
<foo>
    <bar/>
    B.
    <bar/> 
</foo>

This will produce:

<?xml version="1.0"?>
<output>"

    B.

"</output>

Note here that the text-nodes (actually containing only whitespace)
before the first <bar/> and after the second <bar/> are included in
the resulting output; that's why we get the additional empty lines
surrounding the "B.".

Now, the addition of <xsl:strip-space elements="*"/> to the stylesheet
will procude the following:

<?xml version="1.0"?>
<output>"
    B.
    "</output>

The text nodes containing only whitespace, have been removed from the
input XML by <xsl:strip-space elements="*"/>

MSXML does strip such whitespace text-nodes by _default_. So one might
want to use <xsl:strip-space elements="*"/> for compatibility with
the MSXML-XSLT engine.

Regards,

Kasimier

On Sat, 2006-01-21 at 21:35 +0100, Liron wrote:
> Hi Andrew,

[..]

Current Thread