Комбинирование элементов XML на основе определенных значений
Я пытаюсь сгруппировать XML на основе определенных значений узлов:
<bus:TaxList>
<bus:VoPaidTax>
<bus:TaxAmount>4.45</bus:TaxAmount>
<bus:TaxCode>10</bus:TaxCode>
<bus:TaxRate>0.05</bus:TaxRate>
<bus:TaxType>VAT</bus:TaxType>
</bus:VoPaidTax>
<bus:VoPaidTax>
<bus:TaxAmount>6.23</bus:TaxAmount>
<bus:TaxCode>12</bus:TaxCode>
<bus:TaxRate>0.07</bus:TaxRate>
<bus:TaxType>VAT</bus:TaxType>
</bus:VoPaidTax>
<bus:VoPaidTax>
<bus:TaxAmount>6.45</bus:TaxAmount>
<bus:TaxCode>10</bus:TaxCode>
<bus:TaxRate>0.05</bus:TaxRate>
<bus:TaxType>VAT</bus:TaxType>
</bus:VoPaidTax>
<bus:VoPaidTax>
<bus:TaxAmount>9.03</bus:TaxAmount>
<bus:TaxCode>12</bus:TaxCode>
<bus:TaxRate>0.07</bus:TaxRate>
<bus:TaxType>VAT</bus:TaxType>
</bus:VoPaidTax>
</bus:TaxList
Теперь я хочу добавить группу VoPaidTax с одинаковыми TaxCode и Rate.
<bus:TaxList>
<bus:VoPaidTax>
<bus:TaxAmount>10.90</bus:TaxAmount>
<bus:TaxCode>10</bus:TaxCode>
<bus:TaxRate>0.05</bus:TaxRate>
<bus:TaxType>VAT</bus:TaxType>
</bus:VoPaidTax>
<bus:VoPaidTax>
<bus:TaxAmount>15.23</bus:TaxAmount>
<bus:TaxCode>12</bus:TaxCode>
<bus:TaxRate>0.07</bus:TaxRate>
<bus:TaxType>VAT</bus:TaxType>
</bus:VoPaidTax>
</bus:TaxList
И оставить уникальные.
Я пытался что-то вроде этого, но это не похоже на работу Что я делаю не так здесь:
<xsl:template match="bus:TaxList">
<xsl:for-each select="bus:VoPaidTax[not(bus:TaxCode = ../preceding- sibling::*/bus:VoPaidTax/bus:TaxCode) and not(bus:TaxRate= ../preceding- sibling::*/bus:VoPaidTax/bus:TaxRate)]">
<xsl:call-template name="taxCorrection">
<xsl:with-param name="TaxCode">
<xsl:value-of select="bus:TaxCode"/>
</xsl:with-param>
<xsl:with-param name="percent">
<xsl:value-of select="bus:TaxRate"/>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="taxCorrection">
<xsl:param name="TaxCode"/>
<xsl:param name="percent"/>
<xsl:variable name="sumTaxRate">
<xsl:value-of select="sum(../bus:VoPaidTax[bus:TaxCode = $TaxCode and bus:TaxRate =$percent]/bus:TaxAmount)" />
</xsl:variable>
</xsl:template>
Дело в том, что этот шаблон вызывается несколько раз, и сумма, как и предыдущий брат, кажется, не работает. Что я здесь не так делаю?? Я использую XSLT 1.0 Может кто-нибудь, пожалуйста, помогите мне!
2 ответа
Действительно, рассмотрим мюнхенскую группировку, особенно потому, что необходимы ключи для выравнивания цифр для суммирования групп.
<xsl:key name="taxgrp" match="bus:VoPaidTax" use="concat(bus:TaxCode, bus:TaxRate)" />
<xsl:template match="bus:TaxList">
<bus:TaxList>
<xsl:for-each select="bus:VoPaidTax[generate-id()
= generate-id(key('taxgrp', concat(bus:TaxCode, bus:TaxRate))[1])]">
<bus:VoPaidTax>
<bus:TaxAmount>
<xsl:value-of select="sum(key('taxgrp',
concat(bus:TaxCode, bus:TaxRate))/bus:TaxAmount)"/>
</bus:TaxAmount>
<xsl:copy-of select="*[not(local-name()='bus:TaxAmount')]"/>
</bus:VoPaidTax>
</xsl:for-each>
</bus:TaxList>
</xsl:template>
Выход
<bus:TaxList>
<bus:VoPaidTax>
<bus:TaxAmount>10.9</bus:TaxAmount>
<bus:TaxCode>10</bus:TaxCode>
<bus:TaxRate>0.05</bus:TaxRate>
<bus:TaxType>VAT</bus:TaxType>
</bus:VoPaidTax>
<bus:VoPaidTax>
<bus:TaxAmount>15.26</bus:TaxAmount>
<bus:TaxCode>12</bus:TaxCode>
<bus:TaxRate>0.07</bus:TaxRate>
<bus:TaxType>VAT</bus:TaxType>
</bus:VoPaidTax>
</bus:TaxList>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:key name="taxgrp" match="bus:VoPaidTax" use="concat(generate-id(..),bus:TaxCode, bus:TaxRate)" />
<xsl:template match="bus:BsAddOrderPaymentRequestPayload/bus:Request/bus:TotalPaidAmount/bus:TaxList">
<bus:TaxList>
<xsl:for-each select="bus:VoPaidTax[generate-id()
= generate-id(key('taxgrp', concat(generate-id(..),bus:TaxCode, bus:TaxRate))[1])]">
<bus:VoPaidTax>
<bus:TaxAmount>
<xsl:value-of select="sum(key('taxgrp',
concat(generate-id(..),bus:TaxCode, bus:TaxRate))/bus:TaxAmount)"/>
</bus:TaxAmount>
<xsl:copy-of select="*[not(self::bus:TaxAmount)]"/>
</bus:VoPaidTax>
</xsl:for-each>
</bus:TaxList>
</xsl:template>
</xsl:stylesheet>
Добавлен generate-id(..) для каждого ключа, чтобы сохранить группировку в определенном узле, а не во всем документе.