KungWaz
KungWaz

Reputation: 1956

XSL count preceding nodes

I can't figure out how to count the occurance of a node with a given name.

This is my structure:

<xsl:variable name="pageType" select="/verticaldata/context/querystring/parameter[@name = 'type']"/>

<xsl:template match="/">
    <xsl:if test="number(/verticaldata/contents/@totalcount) > 0">
        <xsl:apply-templates select="verticaldata/contents/content"/>
    </xsl:if>
</xsl:template>

<xsl:template match="content">
    <xsl:variable name="itemType" select="contentdata/type">
    <xsl:if test="$pageType = $itemType">
        <xsl:call-template name="displayItem"/>
    </xsl:if>
</xsl:template>

<xsl:template name="displayItem">
    <!-- Here I want to show the item number in the id -->
    <div class="item">
        <xsl:attribute name="id">
            <xsl:value-of select="count(preceding-sibling::content)"/>
        </xsl:attribute>

        <!-- Item renders here -->

    </div>
</xsl:template>

I have tried position() and count(preceding-sibling::content) but they all show the total count not the count of items that passes through the "type" check. How do I get the count of "displayItem" nodes that have been created before?

Is this possible?

// Daniel

Upvotes: 0

Views: 6295

Answers (1)

Tim C
Tim C

Reputation: 70618

What you need to do, I think, is change your preceding-sibling code to check the content type by means of an xpath expression

<xsl:value-of select="count(preceding-sibling::content[contentdata/type = $pageType])"/>

In fact, you could use the same principal in your xsl:apply-templates

<xsl:apply-templates select="verticaldata/contents/content[contentdata/type = $pageType]"/>

This would allow you to do away with the xsl:if in the matching template, which in turn means you could probably do away with the need for having a named template for displayItem too

<xsl:variable name="pageType" select="/verticaldata/context/querystring/parameter[@name = 'type']"/>

<xsl:template match="/">
    <xsl:if test="number(/verticaldata/contents/@totalcount) > 0">
        <xsl:apply-templates select="verticaldata/contents/content[contentdata/type = $pageType]"/>
    </xsl:if>
</xsl:template>

<xsl:template match="content">
    <div class="item">
        <xsl:attribute name="id">
            <xsl:value-of select="count(preceding-sibling::content[contentdata/type = $pageType])"/>
        </xsl:attribute>
          <!-- Item renders here -->
    </div>
</xsl:template>

As an aside, you could use Attribute Value Templates to set the Id of the div here

<div class="item" id="{count(preceding-sibling::content[contentdata/type = $pageType])}">

The curly braces indicate an expression to be evaluated, not output literally.

Upvotes: 1

Related Questions