Thanks,

this made things clear. I wasn´t aware that compare in Xpath compares to any 
preceding nodes not only the first one.

I wanted to archive an Index like:

a | a_c
   | a_d
   | a_a
b| b_a
   | b_d
…
As long as I don´t use substring it worked, if I use substring in the 
comparison (substring(preceding::CCC,1,2)) it does not work.
Because of, as you described, substring is a string operation and uses only the 
first node.

So things get a little bit more complicated here.

Cheers

Sam





Hi, Sam.

Sam Prokop <spro...@4tek.de> wrote on 02/12/2010 08:53:39 AM:
>     <xsl:template match="/">
>         <xsl:apply-templates select="//AAA/BBB">
>             <xsl:sort select="CCC"/>
>         </xsl:apply-templates>
>     </xsl:template>
>
>     <xsl:template match="BBB">
>          <xsl:value-of select="CCC"/> = <xsl:value-of
> select="preceding::CCC"/> : <xsl:value-of select="CCC = preceding::CCC"/><br/>
>     </xsl:template>
>
> Result:
> A=:false
> A=A:true
> A=A:true
> B=A:false
> B=A:true
> B=A:true
> C=A:false
>
> Does the comparison “CCC = preceding::CCC” use the sorted Node-Set
> for preceding and  the select “preceding::CCC” use the document node set?

I think this has more to do with the differences in the meaning of the 
relational operators and of conversion to string than the effect of sorting.

xsl:value-of converts the selected value to string and uses that string value 
to construct a new text node.  That conversion is performed as if the XPath 
string function was applied to the value.[1]  "A node-set is converted to a 
string by returning the string-value of the node in the node-set that is first 
in document order. If the node-set is empty, an empty string is returned."

So when you write xsl:value-of select="preceding::CCC" that selects the all the 
CCC elements that precede the context node (the BBB element) in document order, 
and the conversion to string selects the first of those.  So, except when the 
context node is the first BBB element which has no preceding CCC elements, the 
xsl:value-of is always getting the string value of the very first CCC node - 
that is, "A".

From section 3.4 of XPath 1.0,[2] "If both objects to be compared are 
node-sets, then the comparison will be true if and only if there is a node in 
the first node-set and a node in the second node-set such that the result of 
performing the comparison on the string-values of the two nodes is true."

So when you write, <xsl:value-of select="CCC = preceding::CCC"/>, that selects 
two sets of nodes:  the CCC element children of the BBB element, and all the 
CCC elements that precede that BBB element in document order.  Then, if there 
is node in the first set and a node in the second set whose string values are 
equal, the result of the comparison is true.  When you come to the first BBB 
node that has a CCC child with string value "B", for instance, the result of 
the comparison will be false, but for all subsequent BBB elements with a CCC 
child with string value "B", the result of the comparison must be true.

I hope that helps to clarify things.  If you can describe what you're actually 
trying to do, somebody might be able to suggest how you could write that in 
XSLT.

Thanks,

Henry
[1] http://www.w3.org/TR/xpath/#function-string
[2] http://www.w3.org/TR/xpath/#booleans
------------------------------------------------------------------
Henry Zongaro
XML Transformation & Query Development
IBM Canada Lab   T/L 313-6044;  Phone +1 905 413-6044
mailto:zong...@ca.ibm.com

Reply via email to