I am using XSLT 1.0 I transform the following xml file:
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="test_1.xsl"?> <Features> <Feature item="a1" area="1"></Feature> <Feature item="a1" area="1"></Feature> <Feature item="a2" area="1"></Feature> <Feature item="a2" area="1"></Feature> <Feature item="b1" area="1"></Feature> <Feature item="b1" area="1"></Feature> <Feature item="b2" area="1"></Feature> </Features> via this xsl file:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:key name="KeyStyle" match="Feature" use="@style"/> <xsl:key name="KeyItem" match="Feature" use="@item"/> <xsl:template match="Features"> <html> <xsl:for-each select="Feature[generate-id() = generate-id(key('KeyStyle',@style)[1])]"> <xsl:sort select="@style" order="ascending"/> Table for style (<xsl:value-of select="@style"/>) <xsl:for-each select="key('KeyStyle',@style)"> <xsl:sort select="@item" order="ascending"/> <xsl:if test="not(preceding::*[@item = current()/@item])"> <p>Style=<xsl:value-of select="@style"/></p> <p>Item=<xsl:value-of select="@item"/></p> <p>TotalAreaOf_Items (<xsl:value-of select="@item"/>)=<xsl:value-of select="sum(key('KeyItem',@item)/@area)"/></p> </xsl:if> </xsl:for-each> ---------- <br/><br/> </xsl:for-each> </html> </xsl:template> </xsl:stylesheet> Getting this output:
<html> Table for style (a) <p>Item=a1</p> <p>TotalAreaOf_Items (a1)=4</p> <p>Item=a2</p> <p>TotalAreaOf_Items (a2)=4</p> ----------------- Table for style (b) <p>Item=b1</p> <p>TotalAreaOf_Items (b1)=3</p> <p>Item=b2</p> <p>TotalAreaOf_Items (b2)=3</p> </html> Since substring(@item, 1, 1) statement scans all (a) items ignoring what follows after (a), I apparently get the sum of all items starting with (a) : TotalAreaOf_Items (a1)=4 and TotalAreaOf_Items (a2)=4
instead of the desired : TotalAreaOf_Items (a1)=2 and TotalAreaOf_Items (a2)=2
I try to handle the <xsl:value-of select="sum(key('KeyItem'... with a separate key, but the two prevailing nested xsl:for-each statements have already assigned which way the scanning is performed. Any help will be valuable.
@styleusesubstring(@item, 1, 1), in both thexsl:keydefinition and the calls to thekey()function.