Это может быть достигнуто в XSLT1.0 с помощью метода, называемого группировкой Muenchian.
Сначала вы определяете ключ для поиска элементов line для данного элемента lines , используя атрибут line_id в качестве ключа. Таким образом, для данного элемента lines и атрибута line_id будут возвращены все соответствующие элементы line . Для этого вам понадобится сцепленный ключ.
<xsl:key name="id"
match="line"
use="concat(concat(generate-id(..), ','), @line_id)"/>
Далее необходимо сопоставить элементы line , которые имеют первое вхождение каждого отдельного атрибута line_id в элементе lines . Это достигается следующим образом:
<xsl:apply-templates
select="line[
generate-id() =
generate-id(key('id',concat(concat(generate-id(..),','),@line_id))[1])]" />
т.е. Совпадение line элементов, которые являются первыми элементами в списке для данного ключа.
Затем вы можете получить общее количество, просто суммируя все элементы в ключе
<xsl:value-of
select="sum(key('id', concat(concat(generate-id(..), ','), @line_id))/qty)"/>
Вот полный документ XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="id" match="line" use="concat(concat(generate-id(..), ','), @line_id)"/>
<xsl:template match="/foo">
<newfoo>
<xsl:apply-templates select="lines"/>
</newfoo>
</xsl:template>
<xsl:template match="lines">
<items>
<xsl:apply-templates select="line[generate-id() = generate-id(key('id', concat(concat(generate-id(..), ','), @line_id))[1])]"/>
</items>
</xsl:template>
<xsl:template match="line">
<item>
<item_id>
<xsl:value-of select="@line_id"/>
</item_id>
<quantity>
<xsl:value-of select="sum(key('id', concat(concat(generate-id(..), ','), @line_id))/qty)"/>
</quantity>
</item>
</xsl:template>
</xsl:stylesheet>
Применительно к следующему XML:
<foo>
<lines>
<line line_id="10000">
<qty>10</qty>
</line>
<line line_id="10000">
<qty>4</qty>
</line>
<line line_id="10000">
<qty>12</qty>
</line>
<line line_id="20000">
<qty>1</qty>
</line>
<line line_id="30000">
<qty>4</qty>
</line>
<line line_id="30000">
<qty>6</qty>
</line>
</lines>
<lines>
<line line_id="10000">
<qty>4</qty>
</line>
</lines>
</foo>
Выводится следующий XML:
<newfoo>
<items>
<item>
<item_id>10000</item_id>
<quantity>26</quantity>
</item>
<item>
<item_id>20000</item_id>
<quantity>1</quantity>
</item>
<item>
<item_id>30000</item_id>
<quantity>10</quantity>
</item>
</items>
<items>
<item>
<item_id>10000</item_id>
<quantity>4</quantity>
</item>
</items>
</newfoo>