Re: [xsl] Re: xsl-list Digest 28 May 2008 05:10:01 -0000 Issue 1511

Subject: Re: [xsl] Re: xsl-list Digest 28 May 2008 05:10:01 -0000 Issue 1511
From: "Andrew Welch" <andrew.j.welch@xxxxxxxxx>
Date: Thu, 29 May 2008 12:10:53 +0100
> 1. xsl:value-of can output a sequence of values separated by a given
> separator (which defaults to a single space)

Just to be clear/pedantic,  xsl:value-of adds a single text node to
the result tree - when you call value-of on multiple nodes it will
combine all of them using a separator (default is a space character).

In xslt 1.0 calling value-of on multiple nodes will just add the
string value of the first node to result

For example:



<xsl:value-of select="/root/node"/>

In XSLT 1.0 you get:


..because in 1.0 when you call a function/instruction that expects a
single value with multiple values then it just uses the first.  This
is sometimes known as "first item semantics": xslt 1.0's way of not
throwing an error and producing output at all costs...  It's one of
the areas you need to be aware of when upgrading from 1.0 to 2.0 (as
in when you change version="1.0" to version="2.0", not just running in
backwards compatibility mode which I think simulates this) but I would
say it's poor practice to rely on it anyway.

In 2.0 you get:

"foo bar"

...because in 2.0 xsl:value-of can accept a sequence of items,
outputting each of them with the default separator.

Anyway, to demonstrate how you can get a single text node from
xsl:value-of you can do:

<xsl:value-of separator="xx">
  <xsl:value-of select="/root/node" separator=", "/>

which outputs

"foo, bar"

The inner value-of takes the two items and combines them using the
comma.  The outer value-of just gets a single item of "foo, bar" so
there's nothing to combine using the "xx" separator.

Equally adjacent text nodes are merged, so nested value-of's are pointless:

<xsl:value-of separator="xx">
  <xsl:value-of select="/root/node[1]"/>
  <xsl:value-of select="/root/node[2]"/>
</xsl:value-of> the output is "foobar" as "foo" and "bar" are merged before
the outer value-of gets to them.
If you need to keep them separate then keep them separate then use
xsl:sequence (which keeps them as elements rather text nodes and so
they aren't merged)

<xsl:value-of separator="xx">
  <xsl:sequence select="/root/node[1]"/>
  <xsl:sequence select="/root/node[2]"/>

...produces "fooxxbar"

Hope this is helpful rather than just waffle :)

Andrew Welch

Current Thread