I need help to process following XML document using XSL 1.0, and I don't have the words to describe what the actual problem is.
I have a collection of items collectionA I'd like to process. collectionA is related to collectionB from which I'd like to get the sum of all related num values. The relationship is a many-to-many relationship, defined by the collectionC items, that connects the A and B items.
In any other object model based programming language I would use a loop. Problem is that I don't see how to both loop AND to collect the sum of all values in xslt 1.0...?
<root>
<collectionA>
<id>1</id>
</collectionA>
<collectionA>
<id>2</id>
</collectionA>
<collectionB>
<id>1</id>
<num>11</num>
</collectionB>
<collectionB>
<id>2</id>
<num>22</num>
</collectionB>
<collectionB>
<id>3</id>
<num>33</num>
</collectionB>
<collectionB>
<id>4</id>
<num>44</num>
</collectionB>
<collectionC>
<collectionAid>1</collectionAid>
<collectionBid>1</collectionBid>
<collectionBid>2</collectionBid>
</collectionC>
<collectionC>
<collectionAid>2</collectionAid>
<collectionBid>3</collectionBid>
<collectionBid>4</collectionBid>
</collectionC>
</root>
Expected result is:
<root>
<collectionA>
<id>1</id>
<sum>33</sum>
</collectionA>
<collectionA>
<id>2</id>
<sum>77</sum>
</collectionA>
</root>
Anyone!?
I don't see how to both loop AND to collect the sum of all values
You do not need to do either one of these. All you need is a pair of keys to resolve the cross-references. Then use them to select the related nodes and sum their values:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="b" match="collectionB" use="id" />
<xsl:key name="c" match="collectionC" use="collectionAid" />
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each select="collectionA">
<xsl:copy>
<xsl:copy-of select="id"/>
<sum>
<xsl:value-of select="sum(key('b', key('c', id)/collectionBid)/num)"/>
</sum>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>