Search code examples
xslt-1.0xpath-1.0

How to get sum of immediate next nodes using XSLT 1.0


I have this XML file, where I have these nodes:

<Rows>
    <Row type="Comment">
        <Amount>0.00</Amount>
    </Row>
    <Row type="Spec">
        <Amount>10.00</Amount>
    </Row>
    <Row type="Spec">
        <Amount>10.00</Amount>
    </Row>
    <Row type="Spec">
        <Amount>10.00</Amount>
    </Row>
    <Row type="Comment">
        <Amount>0.00</Amount>
    </Row>
    <Row type="Spec">
        <Amount>20.00</Amount>
    </Row>
    <Row type="Spec">
        <Amount>10.00</Amount>
    </Row>
    <Row type="Spec">
        <Amount>20.00</Amount>
    </Row>
</Rows>

The result should be: COMMENT: 30 COMMENT: 50

These Spec rows will always come after Comment rows. I need to do the sum of those Spec rows which are coming after Comment rows.

I tried to use Preceeding and Following functions in XSLT 1.0 but it is not working:

<xsl:value-of select="sum(../Row[@type='Spec']/Amount][following-sibling::row[1][@type='comment']])"/>

Can someone please help?


Solution

  • I would suggest you try it this way:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    
    <xsl:key name="spec" match="Row[@type='Spec']" use="generate-id(preceding-sibling::Row[@type='Comment'][1])" />
    
    <xsl:template match="Rows">
        <xsl:for-each select="Row[@type='Comment']">
            <xsl:text>COMMENT: </xsl:text>
            <xsl:value-of select="sum(key('spec', generate-id())/Amount)"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:template>
    
    </xsl:stylesheet>