是否可以使用XSLT对此数据求和?

时间:2016-06-18 02:33:30

标签: xml xslt xpath xslt-1.0

是否可以使用XSLT对此数据求和?我有以下数据集

<?xml version="1.0" encoding="utf-8"?>
<data>
    <recordType>EXP</recordType>
      <AppContribAmt>0.0</AppContribAmt>
      <LdgCost>658.82</LdgCost>
      <LabCostIn>0.0</LabCostIn>
      <LabCostOut>0.0</LabCostOut>
      <ServiceCost>0.0</ServiceCost>
      <MatCostIn>0.0</MatCostIn>
      <MatCostOut>0.0</MatCostOut>
      <ToolCostIn>0.0</ToolCostIn>
      <ToolCostOut>0.0</ToolCostOut>
      <recordType>ADD</recordType>
      <AppContribAmt>0.0</AppContribAmt>
      <LdgCost>932.5</LdgCost>
      <LabCostIn>104.64</LabCostIn>
      <LabCostOut>0.0</LabCostOut>
      <ServiceCost>0.0</ServiceCost>
      <MatCostIn>260.36</MatCostIn>
      <MatCostOut>0.0</MatCostOut>
      <ToolCostIn>0.0</ToolCostIn>
      <ToolCostOut>0.0</ToolCostOut>
      <recordType>ADD</recordType>
      <AppContribAmt>0.0</AppContribAmt>
      <LdgCost>932.5</LdgCost>
      <LabCostIn>104.64</LabCostIn>
      <LabCostOut>0.0</LabCostOut>
      <ServiceCost>0.0</ServiceCost>
      <MatCostIn>260.36</MatCostIn>
      <MatCostOut>0.0</MatCostOut>
      <ToolCostIn>0.0</ToolCostIn>
      <ToolCostOut>0.0</ToolCostOut>
      <recordType>ADD</recordType>
      <AppContribAmt>0.0</AppContribAmt>
      <LdgCost>932.5</LdgCost>
      <LabCostIn>104.64</LabCostIn>
      <LabCostOut>0.0</LabCostOut>
      <ServiceCost>0.0</ServiceCost>
      <MatCostIn>260.36</MatCostIn>
      <MatCostOut>0.0</MatCostOut>
      <ToolCostIn>0.0</ToolCostIn>
      <ToolCostOut>0.0</ToolCostOut>
      <recordType>EXP</recordType>
      <AppContribAmt>0.0</AppContribAmt>
      <LdgCost>0.0</LdgCost>
      <LabCostIn>322.95</LabCostIn>
      <LabCostOut>0.0</LabCostOut>
      <ServiceCost>0.0</ServiceCost>
      <MatCostIn>0.0</MatCostIn>
      <MatCostOut>0.0</MatCostOut>
      <ToolCostIn>0.0</ToolCostIn>
      <ToolCostOut>0.0</ToolCostOut>
</data>

我正在尝试将recordType =&#39; EXP&#39;下的值相加。总数和recordType =&#39; ADD&#39;到另一个。这是可能的还是我需要将XML格式更改为这样的东西?

<?xml version="1.0" encoding="utf-8"?>
<data>
    <recordType value='EXP'>
      <AppContribAmt>0.0</AppContribAmt>
      <LdgCost>658.82</LdgCost>
      <LabCostIn>0.0</LabCostIn>
      <LabCostOut>0.0</LabCostOut>
      <ServiceCost>0.0</ServiceCost>
      <MatCostIn>0.0</MatCostIn>
      <MatCostOut>0.0</MatCostOut>
      <ToolCostIn>0.0</ToolCostIn>
      <ToolCostOut>0.0</ToolCostOut>
</recordType>
<recordType value='ADD'>
      <AppContribAmt>0.0</AppContribAmt>
      <LdgCost>932.5</LdgCost>
      <LabCostIn>104.64</LabCostIn>
      <LabCostOut>0.0</LabCostOut>
      <ServiceCost>0.0</ServiceCost>
      <MatCostIn>260.36</MatCostIn>
      <MatCostOut>0.0</MatCostOut>
      <ToolCostIn>0.0</ToolCostIn>
      <ToolCostOut>0.0</ToolCostOut>
</recordType>
</data>

2 个答案:

答案 0 :(得分:1)

我会在第一个XML中使用这样的东西:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:key name="k" match="recordType" use="."/>

  <xsl:template match="recordType[generate-id() = generate-id(key('k', .))]">
    <total name="{.}">
      <xsl:value-of select="sum(key('k', .)
                    /following-sibling::*[not(self::recordType)][preceding-sibling::recordType[1] = current()])"/>
    </total>
  </xsl:template>

  <xsl:template match="text()"/>
</xsl:stylesheet>

输出:

<total name="EXP">981.77</total>
<total name="ADD">3892.5</total>

答案 1 :(得分:1)

这是另一个更复杂的XSLT 1.0选项,但如果你有更大的数据集,它应该更有效率。

*我使用Saxon-HE 9.6测试并复制了您的数据,因此文件为10,353行,此样式表运行时间约为150毫秒,而另一个答案约为1500毫秒(基于“-t”开关的输出)。结果可能因实际数据和不同的处理器而异,因此您可能需要进行测试。

XSLT 1.0

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

  <xsl:key name="recordTypes" match="recordType" use="."/>
  <xsl:key name="byRecordType" match="*[not(self::recordType)]" 
    use="preceding-sibling::recordType[1]"/>

  <xsl:template match="/*">
    <results>
      <xsl:for-each select="recordType[count(.|key('recordTypes',.)[1])=1]">
        <xsl:apply-templates select="."/>
      </xsl:for-each>
    </results>
  </xsl:template>

  <xsl:template match="recordType">
    <sum type="{.}">
      <xsl:value-of select="sum(key('byRecordType',.))"/>
    </sum>
  </xsl:template>

</xsl:stylesheet>

<强>输出

<results>
   <sum type="EXP">981.77</sum>
   <sum type="ADD">3892.5</sum>
</results