Re: [xsl] [string to node]

Subject: Re: [xsl] [string to node]
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Sun, 21 Feb 2010 20:36:39 -0500
At 2010-02-21 20:13 -0500, Syd Bauman wrote:
> > In both cases it seems as though $a contains only 1 thing, a
> > string. (You can test that it is not a node set by using $a in
> > the select= of a for-each -- you should get a runtime error,
> > since it is a string.)
>
> No, it's a result tree fragment, not a string.

Oh, right. Thanks for the correction. (He says with his tail between
his legs.) But if I understand correctly, as a result tree fragment,
only those operations that can be performed on strings are permitted
(i.e., can't do path stuff or predicates), and you can't use a result
tree fragment as the value of select=

Actually, you can do <xsl:value-of select="$rtf"/> ... which gives you the string value of the text nodes in the result tree fragment. It is this RTF-to-string conversion that is happening when you pass a result tree fragment variable as an argument to a function.


of for-each (or apply-
templates, for that matter), because a result tree fragment is not a
node-set, even though when you do get to use one it behaves as node-
set. (And select= of for-each and apply-templates takes a node-set.)

Right ... but <xsl:value-of/> can still be used.


And because a result tree fragment is always a "root" node (in this
case a single text() node),

Not quite. There are two nodes in:


  <xsl:variable name="a">
    <xsl:value-of select="..."/>
  </xsl:variable>

... the document node at the top of the variable and the single text node child of that document node.

count($a) will always return 1, right?

Yes, but for the document node. Which is why you *always* get 1, even for:


  <xsl:variable name="b">
    <c>
      <d/>
    </c>
    <c>
      <d/>
    </c>
    <c>
      <d/>
    </c>
  </xsl:variable>

Further, I think that if the variable is built using select= instead
of content, the variable is a node-set instead of a result tree
fragment, right? I.e.,
      <xsl:variable name="a" select="//dd"/>
      <xsl:value-of select="count($a)"/>
should return 3 (or however many <dd> were in the input instance).

Yes.


But what then would
      <xsl:value-of select="$a"/>
return? I just tried it on my test input, and it returned "one".

In XSLT 1 you get the value of the first node in the node set.


In XSLT 2 you get the concatenation of all of the node values, with a number of nuances: element, attribute, comment and processing instruction nodes return string values, while text nodes return the sequences of Unicode characters in the node, and when two consecutive strings are added to the result tree, a space is injected to separate the two. Other combinations of consecutive values (which are those involving the characters from a text node) are not separated by a space. The separator space can be changed to an arbitrary string by the optional separator= attribute.

I hope this helps.

. . . . . . . . . . . . Ken

p.s. there are still two seats left for the XSLT/XQuery class in March in Prague, and many seats are available for the classes scheduled for San Francisco in April, tentatively Ottawa in May, and then Trondheim in June.


-- XSLT/XQuery training: after http://XMLPrague.cz 2010-03-15/19 XSLT/XQuery training: San Carlos, California 2010-04-26/30 Principles of XSLT for XQuery Writers: San Francisco,CA 2010-05-03 XSLT/XQuery/UBL/Code List training: Trondheim,Norway 2010-06-02/11 Vote for your XML training: http://www.CraneSoftwrights.com/s/i/ Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread