Re: [xsl] RE: Returning A Tree

Subject: Re: [xsl] RE: Returning A Tree
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Thu, 6 Sep 2001 09:59:19 +0100
Hi Darren,

> Why is the output the same (my understanding is that GiveMeA should
> give me a text node, but I thought that GiveMeB would be a node
> set)?

When you set the value of a variable using its content, you always get
a result tree fragment. In your example, you are setting $A and $B
using their content, as follows:

  <xsl:variable name="A">
    <xsl:call-template name="selectNodes">
      <xsl:with-param name="doWhat" select="'GiveMeA'" />
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="B">
    <xsl:call-template name="selectNodes">
      <xsl:with-param name="doWhat" select="'GiveMeB'" />
    </xsl:call-template>
  </xsl:variable>

The selectNodes templates generates different things for each of the
variables, such that the equivalent xsl:variable elements would be:

  <xsl:variable name="A">A1A2A3A4</xsl:variable>
  <xsl:variable name="B">
    <B>B1</B><B>B2</B><B>B3</B><B>B4</B>
  </xsl:variable>

The result tree fragments are like miniature node trees. $A looks
like:

  root
    +- text: A1A2A3A4

while $B looks like:

  root
    +- element: B
    |   +- text: B1
    +- element: B
    |   +- text: B2
    +- element: B
    |   +- text: B3
    +- element: B
        +- text: B4

In XSLT 1.0, result tree fragments are special beasts that, unlike
node sets, cannot be referenced into - you can't use paths to access
values within a result tree fragment. Once it's constructed, you're
stuck with it as it is.

However, it looks as though you're using a processor that has
implemented the XSLT 1.1 working draft (otherwise you'd be getting
errors when you try to do <xsl:for-each
select="$A">...</xsl:for-each>). The XSLT 1.1 working draft doesn't
make the distinction between result tree fragments and node sets, so
$A and $B are each node sets containing a single root node (the tops
of the two trees illustrated above).

The reason, then, that you aren't getting the output that you expect
is that you're counting and getting the value of the root nodes of
these node trees, rather than the children of the root node. If you
try:

  <xsl:for-each select="$A/node()">...</xsl:for-each>
  <xsl:for-each select="$B/node()">...</xsl:for-each>
  <xsl:value-of select="count($B/node())" />

then you will get the results that you are after.

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread