Это преобразование (64 строки):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kColByPosAndVal" match="column"
use="concat(count(preceding-sibling::*),
'+',
sum)"/>
<xsl:key name="kIdByVal" match="column/@id"
use="."/>
<xsl:template match="/*">
<xsl:variable name="vsum1" select=
"sum(stats[@set=1]/*/column
[not(key('kColByPosAndVal',
concat(count(preceding-sibling::*),
'+',
sum)
)[2]
)])"/>
<xsl:variable name="vsum2" select=
"sum(stats[@set=2]/*/column
[not(key('kColByPosAndVal',
concat(count(preceding-sibling::*),
'+',
sum)
)[2]
)])"/>
Set 1 Set 2 Diff(Set 1 - Set 2)
Total (Diff) <xsl:text/>
<xsl:value-of select="$vsum1"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$vsum2"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$vsum1 -$vsum2"/>
<xsl:text>
</xsl:text>
<xsl:for-each select=
"*/*/column/@id
[generate-id()
= generate-id(key('kIdByVal',.)[1])
]
[not(key('kColByPosAndVal',
concat(count(../preceding-sibling::*),
'+',
../sum)
)[2]
)]">
<xsl:variable name="vcolSet1" select=
"/*/stats[@set=1]/*/column[@id=current()]/sum"/>
<xsl:variable name="vcolSet2" select=
"/*/stats[@set=2]/*/column[@id=current()]/sum"/>
Column <xsl:value-of select=".+1"/><xsl:text/>
<xsl:text> </xsl:text>
<xsl:value-of select="$vcolSet1"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$vcolSet2"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$vcolSet1 -$vcolSet2"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
при применении к предоставленному документу XML:
<export>
<stats set="1">
<columns>
<column id="0">
<sum>100</sum>
</column>
<column id="1">
<sum>102</sum>
</column>
<column id="2">
<sum>12</sum>
</column>
</columns>
</stats>
<stats set="2">
<columns>
<column id="0">
<sum>100</sum>
</column>
<column id="1">
<sum>101</sum>
</column>
<column id="2">
<sum>19</sum>
</column>
</columns>
</stats>
</export>
дает желаемый, правильный результат :
Set 1 Set 2 Diff(Set 1 - Set 2)
Total (Diff) 114 120 -6
Column 2 102 101 1
Column 3 12 19 -7
Объяснение
Ключ с именем kColByPosAndVal
используется для выбора всех столбцов, которые имеют заданную позицию (среди всех column
братьев и сестер) и заданное значение для их sum
дочернего элемента.
Ключ с именем kIdByVal
используется в мюнхенской группировке для поиска всех различных значений атрибута id
.
Два итога рассчитываются суммированием только тех столбцов, чья клавиша kColByPosAndVal
выбирает только один элемент column
(если он выбирает два элемента column
, они оба совпадают позиции и имеют одинаковые sum
).
Остальное должно быть легко понять .