【问题标题】:Remove duplicate parent node based on child node and add specific element values in the concerning node根据子节点删除重复的父节点并在相关节点中添加特定元素值
【发布时间】:2022-01-06 12:31:29
【问题描述】:

我想将值的“TotalAmount”和“Tax”与//Category/ID 作为唯一值相加。 XSLT 必须删除重复项并对已删除重复项的值求和。因此,对于本示例,唯一 ID“S”是重复的,应将其删除,并将所需的值添加到另一个“S”。我无法让 XSLT 工作。

输入示例:

   <root>
    <Total>
      <TotalAmount currencyID="EUR">100.00</TotalAmount>
      <Tax currencyID="EUR">20.00</Tax>
      <Category>
        <ID>S</ID>
        <Percent>21.000</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
    <Total>
      <TotalAmount currencyID="EUR">150.00</TotalAmount>
      <Tax currencyID="EUR">20.00</Tax>
      <Category>
        <ID>S</ID>
        <Percent>21.000</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
    <Total>
      <TotalAmount currencyID="EUR">200.00</TotalAmount>
      <Tax currencyID="EUR">0</Tax>
      <Category>
        <ID>O</ID>
        <Percent>0</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
</root>

XSLT

<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="kByP" match="Category" use="ID"/>

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

 <xsl:template match=
   "Category[generate-id()
           =
            generate-id(key('kByP', ID)[1])
           ]">
  <xsl:copy>
      <xsl:apply-templates select="node()|@*">
         <xsl:with-param name="pNewValue" select=
         "sum(key('kByP', ID)/TotalAmount)"/>
      </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="Total"/>

 <xsl:template match="TotalAmount/text()">
  <xsl:param name="pNewValue"/>
  <xsl:value-of select="$pNewValue"/>
 </xsl:template>
</xsl:stylesheet>

需要的输出:

<root>
    <Total>
      <TotalAmount currencyID="EUR">250.00</TotalAmount>
      <Tax currencyID="EUR">40.00</Tax>
      <Category>
        <ID>S</ID>
        <Percent>21.000</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
    <Total>
      <TotalAmount currencyID="EUR">200.00</TotalAmount>
      <Tax currencyID="EUR">0</Tax>
      <Category>
        <ID>O</ID>
        <Percent>0</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
</root>

【问题讨论】:

    标签: xslt


    【解决方案1】:

    我会从身份转换模板加上您已更改为 &lt;xsl:key name="kByP" match="Total" use="Category/ID"/&gt; 的密钥开始,然后有

    <xsl:template match="Total[not(generate-id() = generate-id(key('kByP', Category/ID)[1]))]"/>
    

    然后

    <xsl:template match="TotalAmount | Tax">
      <xsl:copy>
       <xsl:apply-templates select="@*"/>
       <xsl:value-of select="sum(key('kByP', ../Category/ID)/*[name() = name(current())])"/>
     </xsl:copy>
    </xsl:template>
    

    所以完整的代码是

    <xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
      
      <xsl:key name="kByP" match="Total" use="Category/ID"/>
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
      
      <xsl:template match="Total[not(generate-id() = generate-id(key('kByP', Category/ID)[1]))]"/>
    
      <xsl:template match="TotalAmount | Tax">
        <xsl:copy>
         <xsl:apply-templates select="@*"/>
         <xsl:value-of select="format-number(sum(key('kByP', ../Category/ID)/*[name() = name(current())]), '0.00')"/>
       </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 感谢分享,我会努力解决的。我现在确实得到了一些结果,但还没有所需的数据。
    • @keeskroket, xsltfiddle.liberty-development.net/bF2MmXa 似乎有正确的总和,我想是为了改进你想使用的数字格式,例如&lt;xsl:value-of select="format-number(sum(key('kByP', ../Category/ID)/*[name() = name(current())]), '0.00')"/&gt; 但这只是一个表面问题。
    • 现在似乎可以正常工作了。谢谢马丁,你最后的回答对我帮助很大。
    猜你喜欢
    • 2021-05-17
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    相关资源
    最近更新 更多