2010-08-15 80 views
2

我正在寻找一个XSL来按节点对XML进行排序和分组,然后通过另一个节点对其进行求和。我将不得不使用XSLT 1.0。如何使用XSLT 1.0对XMl进行排序?

这是我的XML。 排序后,我需要有一个新的XML排序和由<TransCode>分组,所有<TransAmt>应该为每个组求和。我正在为此任务寻找XSL。任何帮助表示赞赏。排序后,新的XML应该只有三个节点按照<TransCode>的升序排序。所有<TransAmt>必须加在一起。

这里是我的XML:

<Transactions> 
<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>12.30</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0002</TransCode> 
    <TransType>Cash</TransType> 
    <TransAmt>26.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>25.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0015</TransCode> 
    <TransType>FinanceCharge</TransType> 
    <TransAmt>25.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0002</TransCode> 
    <TransType>Cash</TransType> 
    <TransAmt>50.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>40.00</TransAmt> 
</Transaction> 
</Transactions> 
+0

您是要我们为您编写XSL吗?也许你可以发布你提出的XSL并告诉我们你有什么问题和问题?您想要的输出文档样本也可以帮助回答问题。 – Oded 2010-08-15 16:13:26

+0

好问题(+1)。请参阅我的答案,以获得完整有效的解决方案和关键想法的解释。 :) – 2010-08-15 19:22:22

回答

0

XSL已建成通过<xsl:sort>元素排序,并使用XPath sum功能总结。

两者都受XSLT 1.0支持。

你有什么问题使用这些?

1

这种转变

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*" /> 

<xsl:key name="kTransByCode" 
    match="Transaction" use="TransCode"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/Transactions"> 
    <Transactions> 
    <xsl:apply-templates select= 
    "Transaction[generate-id() 
       = 
       generate-id(key('kTransByCode', 
            TransCode 
           )[1] 
          ) 
       ] 
    "> 
    <xsl:sort select="TransCode" data-type="number"/> 
    </xsl:apply-templates> 
    </Transactions> 
</xsl:template> 

<xsl:template match="TransAmt"> 
    <TransAmt> 
    <xsl:value-of select= 
    "sum(key('kTransByCode',../TransCode)/TransAmt)"/> 
    </TransAmt> 
</xsl:template> 
</xsl:stylesheet> 

时所提供的XML文档应用:

<Transactions> 
<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>12.30</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0002</TransCode> 
    <TransType>Cash</TransType> 
    <TransAmt>26.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>25.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0015</TransCode> 
    <TransType>FinanceCharge</TransType> 
    <TransAmt>25.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0002</TransCode> 
    <TransType>Cash</TransType> 
    <TransAmt>50.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>40.00</TransAmt> 
</Transaction> 
</Transactions> 

产生想要的,正确的结果

<Transactions> 
    <Transaction> 
     <TransCode>0002</TransCode> 
     <TransType>Cash</TransType> 
     <TransAmt>76</TransAmt> 
    </Transaction> 
    <Transaction> 
     <TransCode>0008</TransCode> 
     <TransType>Purchase</TransType> 
     <TransAmt>77.3</TransAmt> 
    </Transaction> 
    <Transaction> 
     <TransCode>0015</TransCode> 
     <TransType>FinanceCharge</TransType> 
     <TransAmt>25</TransAmt> 
    </Transaction> 
</Transactions> 

请注意

  1. 用于分组的Muenchian方法。

  2. 使用密钥允许简单高效地总和每个转码。

  3. 使用标识规则复制原样大部分元素,并被匹配输出中不同元素的模板覆盖。

+0

+1好答案!但是,我认为如果你匹配“交易中的第一”和“TransAmt/text()”,它可能不那么冗长。我这么说是因为有些人抱怨XSLT是冗长的,你知道的。 – 2010-08-16 20:08:34