xsl-list
[Top] [All Lists]

[xsl] Determining the position of a specific node in the context

2006-10-19 16:24:12
Using: XPath 1

The task: I want to determine if in the current context, a node with
certain properties comes before another.

Example:

<root>
  <A/>
  <B/>
  <C/>
</root>

I want to know whether <B/> comes before <C/>. So I thought, I would
check whether the context position of <B/> is less than the context
position of <C/> in the context made up of select="/root/node()".

My first try:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:template match="root">
  <xsl:if test="node()[self::B]/position() &lt; node()[self::C]/position()">
    <xsl:message>B comes before C.</xsl:message>
  </xsl:if>
</xsl:template>

This gives an error in XSLT1 processors (Xalan, Saxon 6) saying position
() is not a valid element test. (It sure is not.) 

[Side note: Testing the above in Saxon 8 (XSLT2, XPath2) does not give
an error or warning, but the test simply evaluates to false. So, "node()
[self::B]/position()" must be a legal XPath 2 expression - what does it
actually do?]


So I am back to the basic question, "How do I retrieve the position of a
certain node in the context?"

Next try:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:template match="root">
  <xsl:if test="count(B[1]/preceding-sibling::node()) 
                &lt; count(C[1]/preceding-sibling::node())">
    <xsl:message>B comes before C.</xsl:message>
  </xsl:if>
</xsl:template>

This actually works, but it looks really cumbersome to me.

Is there a better way to do this?

Regards, Christian.


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--