开发者

How to sort an XMl using XSLT 1.0?

开发者 https://www.devze.com 2023-01-12 03:38 出处:网络
I\'m looking for an XSL to sort and group an XML by a node andsum by another node.I will have to use XSLT 1.0.

I'm looking for an XSL to sort and group an XML by a node and sum by another node. I will have to use XSLT 1.0.

Here is my XML. After sorting I need to have a new XML sorted and Grouped by <TransCode>, and all <TransAmt> should be summed for each group. I'm looking for the XSL for this task. Any help is appreciated. After sorting new XML should have only three nodes sorted in ascending order of <TransCode>. All the <TransAmt> must be added together.

Here is my 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>


This transformation:

<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>

when applied on the provided XML document:

<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>

produces the wanted, correct result:

<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>

Do note:

  1. The Muenchian method for grouping is used.

  2. The use of keys allows for easy and efficient summation per transcode.

  3. The identity rule is used to copy as-is most elements and is overridden by templates matching elements that will be different in the output.


XSL has built in sorting through the <xsl:sort> element, and summing using the XPath sum function.

Both are supported in XSLT 1.0.

What are the issues you are having using these?

0

精彩评论

暂无评论...
验证码 换一张
取 消