Re: [xsl] SOLVED: [xsl] xsl2 saxon8B stripping off unwanted separation characters

Subject: Re: [xsl] SOLVED: [xsl] xsl2 saxon8B stripping off unwanted separation characters
From: David Carlisle <davidc@xxxxxxxxx>
Date: Mon, 10 Jul 2006 12:36:42 +0100
> Basically, it's a text taken from a web page, where
> there is one and only one <a> element into a <td>.

you may have just one a in each td but if you have more than one td
element that has an a then td/a will select more than one node
and so <xsl:value-of select=fn:normalize-space("td/a")/>  will generate
an error. (You don't need the fn: prefix and could write that as
<xsl:value-of select=normalize-space("td/a")/> 


<xsl:value-of select="normalize-space(td/a[1])"/>

That td/a[1] will select the same nodes as td/a in the situatation that
you describe, you need
(td/a)[1]
if you want to just take the first a and silently discard all the others.
td/a[1] selects the first 1 from each td (but as there is only one a in
each td this is the same as td/a)
(td/a)[1] selects all the td/a grandchildren and then selects the first
of these.

> <xsl:value-of separator=" " select="td/a/normalize-space()"/>
Yes, that gives the sequence of all the a's, normalized.

> It is quite interesting to observe that this solution
> doesn't work with Saxon6.5.5 or with Xalan

the syntax with a string-valued function at the end of an Xpath is
XPath2 only so not supported in XSLT1 processors such as saxon 6 or
xalan.

> For Saxon 6.5.5 and Xalan, normalize-space should
> enclose the Xpath.
> For Saxon 8B, normalize-space should be apended
> to the Xpath.

Not really, it depends on what output you want.

normalize-space((td/a)[1])

would work in all cases and gives, on XSLT1 processors, the same answer as
normalize-space(td/a)
in XSLT1 all later a elements are silently discarded, in xslt2 this is
an error.

If you _want_ all the a elements not just the first  then in xslt2 you
can use

<xsl:value-of separator=" " select="td/a/normalize-space()"/>

or in XSLT1 you can use

<xsl:for-each select="td/a">
 <xsl:value-of select="."/>
 <xsl:if test="position()!=last()"><xsl:text> </xsl:text></xsl:if>
</xsl:for-each>

Which would also work in XSLT2.

David

Current Thread