Re: [xsl] Determine position in node sequence based on criteria

Subject: Re: [xsl] Determine position in node sequence based on criteria
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Wed, 30 Jun 2010 10:39:36 +0100
In XQuery you could do

for $s at $p in ../s where matches($s/@c, '^[ab]$') and matches($s, $re) return $p

The nearest equivalent in XPath 2.0 is

for $p in 1 to count(../s), $s in (../s)[$p] return
if (matches($s/@c, '^[ab]$') and matches($s, $re)) then $p else ()

But I agree it's rather cumbersome.

Michael Kay
Saxonica


On 30/06/2010 00:13, Houghton,Andrew wrote:
I'm have a problem trying to come up with an XPath expression that will determine the position of a node in a node sequence (terminology?) based on some criteria. I have some XML that looks like:

<r>
  <f>
   <s>...</s>
   <s>...</s>
   <s>...</s>
  </f>
</r>

I have a template rule which is at one of the<s> nodes, e.g.:

<xsl:template match="s[@c = 'c']" />

inside that template I'm trying to figure out which other<s> ends in a parenthical expression if and only if an attribute has a certain value. So I started out with this:

<xsl:template match="s[@c = 'c']">
   <xsl:variable name="re" as="xsd:string" select="'(\([^)]+\))\s*$'" />
   <xsl:variable name="pos" as="xsd:integer*">
     <xsl:for-each select="../s">
       <xsl:if test="matches(@c, '^[ab]$') and matches(., $re)">
         <xsl:sequence select="position()" />
       </xsl:if>
     </xsl:for-each>
   </xsl:variable>
</xsl:template>

Great this does exactly what I want, but it seems to me that I should be able to construct an XPath expression and use a select attribute on the $pos variable. So given the XML:

<r>
   <f>
     <s c="a">123</s>
     <s c="b">456 (abc)</s>
     <s c="c" />
   </f>
</r>

I should be able to construct an equivalent XPath expression that would give me a position of 2. My first attempt was:

../s[matches(@c, '^[ab]$') and matches(., $re)]/position()

obviously wrong since it will always return 1, given the above XML, e.g., I need the position() in ../s not the position() of the resulting nodeset from the match criteria. So right now I'm stumpped out of ideas in how to construct the XPath to give me the position. Anybody have any suggestions to offer...

Thanks, Andy.

Current Thread