RE: [xsl] Xpath - count preceding-siblings matching some condition

Subject: RE: [xsl] Xpath - count preceding-siblings matching some condition
From: "Angela Williams" <Angela.Williams@xxxxxxxxxxxxxxxxxx>
Date: Mon, 30 Apr 2007 12:43:55 -0500
Typo below - I meant:
<!-- I intend this test to mean "If the next row in the list has a
column number less than this column number, count all the rows preceding
this one whose column number is *greater* than the column number of the
row
following it. -->

Thanks!
Angela

-----Original Message-----
From: Angela Williams
Sent: Monday, April 30, 2007 12:33 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [xsl] Xpath - count preceding-siblings matching some condition

I can't seem to get my xpath correct. (XSLT 2.0)  Besides my incorrect
xpath, is there a better way to do this?

I have data representing a table and need to increment the row number
when the column number of the following-sibling is less than the current
column number. There is no pattern to the data - a row might have any
column missing (i.e. empty).

The Xpath Visualizer gives me the correct number on the following
statement, but Saxon (via Oxygen) gives an error - A sequence of more
than one item is not allowed as the second operand of lt:

count(preceding-sibling::a[@col-nbr lt preceding-sibling::a/@col-nbr])+2

<!-- The +2 is to accommodate the first row, which doesn't have a
preceding-sibling, and the new row number. ==>

Data:
<data>
  <a   col-nbr="1"   row-nbr="1"  />
  <a   col-nbr="2"   row-nbr="1"  />
  <a   col-nbr="1"   row-nbr="1"  />
  <a   col-nbr="2"   row-nbr="1"  />
  <a   col-nbr="3"   row-nbr="2"  />
  <a   col-nbr="2"   row-nbr="2"  />
  <a   col-nbr="3"   row-nbr="2"  />
  <a   col-nbr="1"   row-nbr="2"  />
  <a   col-nbr="2"   row-nbr="2"  />
  <a   col-nbr="3"   row-nbr="2"  />
</data>

Desired Output:
<table>
  <b  col-nbr="1"   row-nbr="1"  />
  <b  col-nbr="2"   row-nbr="1"  />
  <b  col-nbr="1"   row-nbr="2"  />
  <b  col-nbr="2"   row-nbr="2"  />
  <b  col-nbr="3"   row-nbr="2"  />
  <b  col-nbr="2"   row-nbr="3"  />
  <b  col-nbr="3"   row-nbr="3"  />
  <b  col-nbr="1"   row-nbr="4"  />
  <b  col-nbr="2"   row-nbr="4"  />
  <b  col-nbr="3"   row-nbr="4"  />
</table>

<xsl:template match="/">
 <xsl:variable name="tmp-table" select="//data/a"/>
  <table>
    <xsl:for-each select="$tmp-table">
      <xsl:variable name="col" select="@col-nbr"/>
      <xsl:variable name="row">
        <xsl:choose>
<!-- I intend this test to mean "If the next row in the list has a
column number less than this column number, count all the rows preceding
this one whose column number is less than the column number of the row
following it. -->
          <xsl:when test="following-sibling::a
                                [position()=1 and @col-nbr lt $col]">
            <xsl:value-of select="count(preceding-sibling::a
                     [@col-nbr gt following-sibling::a/@col-nbr])+2"/>
          </xsl:when>
          <xsl:otherwise>1</xsl:otherwise>
         </xsl:choose>
       </xsl:variable>

      <b col-nbr="{@col-nbr}" row-nbr="{$row}" />
    </xsl:for-each>
  </table>
</xsl:template>

Thanks!
Angela Williams
Software Developer
The 401k Company, A Charles Schwab Company
98 San Jacinto Blvd. ~ Suite 1100 ~ Austin, TX 78701
Office: 512.344.1547 ~ Fax: 512.397.6656
Angela.Williams@xxxxxxxxxxxxxxxxxx

Current Thread