XSL条件求和

时间:2011-09-06 14:29:53

标签: xml xslt

我正在尝试转换xml。旧的xsl是由其他人编写的,它非常静态,查找每个节点并写入它们。但我需要将其改为动态方式。这是xml文件(简化版):

<?xml version="1.0" encoding="UTF-8"?>
 <csprint>
  <csrequest>
   <p:Body xmlns:p="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="wsdl.http://isbank.com/OpSvcs/PaymentMgmtProcessing/TaxCollection/Service/V1" xmlns:v1_1="http://isbank.com/OpSvcs/PaymentMgmtProcessing/TaxCollection/Service/V1" xmlns:v1_2="http://isbank.com/OpSvcs/PaymentMgmtProcessing/Tax/Schema/V1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <v1_1:collect>
      <v1_1:collectionData>
       <v1_2:taxOfficeNo>34256</v1_2:taxOfficeNo>
       <v1_2:mainTaxCode>9077</v1_2:mainTaxCode>
       <v1_2:debtLineItem>
        <v1_2:taxCode>1086</v1_2:taxCode>
        <v1_2:installmentNumber>1</v1_2:installmentNumber>
        <v1_2:dueDate>2011-02-28</v1_2:dueDate>
        <v1_2:amount>
         <amount>174134.40</amount>
        </v1_2:amount>
        <v1_2:taxShortName>Y.DIŞI ÇKŞ.H</v1_2:taxShortName>
       </v1_2:debtLineItem>
       <v1_2:debtLineItem>
        <v1_2:taxCode>1086</v1_2:taxCode>
        <v1_2:installmentNumber>1</v1_2:installmentNumber>
        <v1_2:dueDate>2011-02-28</v1_2:dueDate>
        <v1_2:amount>
          <amount>174134.40</amount>
        </v1_2:amount>
        <v1_2:taxShortName>Y.DIŞI ÇKŞ.H</v1_2:taxShortName>
      </v1_2:debtLineItem>
      <v1_2:debtLineItem>
        <v1_2:taxCode>9014</v1_2:taxCode>
        <v1_2:installmentNumber>1</v1_2:installmentNumber>
        <v1_2:dueDate>2011-02-28</v1_2:dueDate>
        <v1_2:amount>
          <amount>174134.40</amount>
        </v1_2:amount>
        <v1_2:taxShortName>Y.DIŞI ÇKŞ.H</v1_2:taxShortName>
      </v1_2:debtLineItem>
      <v1_2:debtLineItem>
        <v1_2:taxCode>9014</v1_2:taxCode>
        <v1_2:installmentNumber>1</v1_2:installmentNumber>
        <v1_2:dueDate>2011-02-28</v1_2:dueDate>
        <v1_2:amount>
          <amount>174134.40</amount>
        </v1_2:amount>
        <v1_2:taxShortName>Y.DIŞI ÇKŞ.H</v1_2:taxShortName>
      </v1_2:debtLineItem>
    </v1_1:collectionData>
  </v1_1:collect>
  </p:Body>
 </csrequest>
</csprint>

这是我的条件:

if (mainTaxCode == 9077 && taxCode == 1086)
  sum /debtLineItem/amount/amount of all 1086 nodes and write just once
else
  write all

并且对于此实例,结果应该类似于

TaxCode      DueDate      Amount
  1086     2011-02-28    348268.80
  9014     2011-02-28    174134.40
  9014     2011-02-28    174134.40

我无法继续前进,不断总结所有3个值。任何帮助赞赏。 感谢..

2 个答案:

答案 0 :(得分:1)

此转换完全根据描述的条件输出所需数据(我认为:P)。此外,条件值是参数化的(默认为9007和1086)。

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:v1_1="http://isbank.com/OpSvcs/PaymentMgmtProcessing/TaxCollection/Service/V1"
    xmlns:v1_2="http://isbank.com/OpSvcs/PaymentMgmtProcessing/Tax/Schema/V1">

    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:param name="mainTaxCode" select="9077"/>
    <xsl:param name="taxCode" select="1086"/>

    <xsl:key name="k" match="v1_2:debtLineItem" 
        use="v1_2:taxCode"/>

    <xsl:template match="v1_1:collect">
        <xsl:apply-templates select="
            v1_1:collectionData
                [v1_2:mainTaxCode=$mainTaxCode]/
                v1_2:debtLineItem
                    [generate-id() 
                    = generate-id(key('k', v1_2:taxCode)[1])]
                    [v1_2:taxCode=$taxCode]
            |
            v1_1:collectionData/
                v1_2:debtLineItem
                    [not(v1_2:taxCode=$taxCode)]"/>
    </xsl:template>

    <xsl:template match="v1_2:debtLineItem">
        <xsl:value-of select="concat(
            v1_2:taxCode, ' ', 
            v1_2:dueDate, ' ')"/>
        <xsl:apply-templates select="v1_2:taxCode[.=$taxCode]" mode="sum"/>
        <xsl:apply-templates select="v1_2:taxCode[.!=$taxCode]"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

    <xsl:template match="v1_2:taxCode" mode="sum">
        <xsl:value-of select="
            format-number(sum(key('k',.)/v1_2:amount/*), '#.00')"/>
    </xsl:template>

    <xsl:template match="v1_2:taxCode">
        <xsl:value-of select="format-number(../v1_2:amount, '#.00')"/>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

如果我理解正确:此模板按v1_2:taxCode分组并加v1_2:amount/amount

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:v1_2="http://isbank.com/OpSvcs/PaymentMgmtProcessing/Tax/Schema/V1">

    <xsl:output method="text" indent="yes" />

    <xsl:key name="k" match="v1_2:debtLineItem" use="v1_2:taxCode"/>

    <xsl:template match="/">
        <xsl:apply-templates select="//v1_2:debtLineItem[generate-id(.) = generate-id(key('k', v1_2:taxCode))]"/>
    </xsl:template>

    <xsl:template match="v1_2:debtLineItem">
        <xsl:value-of select="concat(
                      v1_2:taxCode, ' ', 
                      v1_2:dueDate, ' ', 
                      format-number(sum(//v1_2:debtLineItem[v1_2:taxCode = current()/v1_2:taxCode]/v1_2:amount/*), '#.00'))"/>
        <xsl:text>&#xD;&#xA;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

输出:

1086 2011-02-28 348268.80
9014 2011-02-28 174134.40