Search code examples
xmlxslt

XSLT - Count preceding within ancestor


I have a xml structure that looks like this simplified:

<document>
    <page>
        <viewport>
            <text>page1 text1</text>
            <text>page1 text2</text>
            <text>page1 text3</text>
            <viewport>
                <text>page1 text4</text>
                <text>page1 text5</text>
                <text>page1 text6</text>
            </viewport>
        </viewport>
        <viewport>
            <text>page1 text7</text>
            <text>page1 text8</text>
            <text>page1 text9</text>
        </viewport>
    </page>
    <page>
        <viewport>
            <text>page2 text1</text>
            <text>page2 text2</text>
            <text>page2 text3</text>
        </viewport>
        <viewport>
            <text>page2 text4</text>
            <text>page2 text5</text>
            <text>page2 text6</text>
            <viewport>
                <text>page2 text7</text>
                <text>page2 text8</text>
                <text>page2 text9</text>
            </viewport>
        </viewport>
    </page>
</document>

I would like to count at how many text elements i am on per page.

My template looks like this

<xsl:template match="text">
  <xsl:variable name="page-number" select="count(preceding::page) + 1"/>
  <xsl:variable name="position-in-page" select="count(preceding::*[name() = name(current())])"/>
</xsl:template>

For an example on page2 text8 element i want page-number = 2 and position-in-page = 8

I know that preceding:: is not right here for position-in-page...

I think i need a mix of preceding-sibling and ancestor but i just cant figure out...


Solution

  • Try:

    <xsl:number count="page"/>
    

    for the page number, and:

    <xsl:number level="any" from="page"/>
    

    for the position of text in its page.

    This is assuming you want to preserve the internal hierarchy of the viewports. Otherwise this could possibly be much simpler.