在XSLT执行SUM操作(Perform SUM operation in XSLT)

2019-10-29 03:07发布

在下面的输入,我们必须检查供应商代码,如果它是匹配到任何节点的供应商代码的那么我们必须执行求和操作上Quantity.otherwise直接映射的数量。

输入:

<Move-Afile>
  <Afile>
    <Item>
    <suppliercode>1</suppliercode>
      <PackNumber>1234</PackNumber>
      <Quantity>12</Quantity>
    </Item>
    <Item>
    <suppliercode>2</suppliercode>
      <PackNumber>567</PackNumber>
      <Quantity>3</Quantity>
    </Item>
    <Item>
    <suppliercode>1</suppliercode>
      <PackNumber>567</PackNumber>
      <Quantity>8</Quantity>
    </Item>
    <Item>
    <suppliercode>3</suppliercode>
      <PackNumber>126</PackNumber>
      <Quantity>11</Quantity>
    </Item>
    <Item>
    <suppliercode>4</suppliercode>
      <PackNumber>876</PackNumber>
      <Quantity>32</Quantity>
    </Item>
  </Afile>
</Move-Afile>

如果供应商代码等于然后数量进行求和操作,否则直接映射的数量。

输出:

<A>
  <target>
    <Item>
    <suppliercode>1</suppliercode>
      <PackNumber>1234</PackNumber>
      <Quantity>20</Quantity>
    </Item>
    <Item>
    <suppliercode>2</suppliercode>
      <PackNumber>567</PackNumber>
      <Quantity>3</Quantity>
    </Item>
    <Item>
    <suppliercode>1</suppliercode>
      <PackNumber>567</PackNumber>
      <Quantity>20</Quantity>
    </Item>
    <Item>
    <suppliercode>3</suppliercode>
      <PackNumber>126</PackNumber>
      <Quantity>11</Quantity>
    </Item>
    <Item>
    <suppliercode>4</suppliercode>
      <PackNumber>876</PackNumber>
      <Quantity>32</Quantity>
    </Item>
  </target>
</A>

我需要在像下面单独的临时变量之和的逻辑。

<varaible name=tempvar>
<xsl:choose>
<xsl:when suppliercode=suppliercode>

<xsl:value-of select=sum(quntity)/>

<xsl:when>

<xsl:otherwise>

<xsl:value-of select=quntity/>

</xsl:otherwise>

</xsl:choose>

</variable>

Answer 1:

这个样式表做了你所需要的。 它复制所有的元素Item下,并具有特殊的模板修改的值Quantity通过将所有的值Quantity从要素Item具有相同值的元素suppliercode

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <A>
      <target>
        <xsl:apply-templates select="Move-Afile/Afile/Item"/>
      </target>
    </A>
  </xsl:template>

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

  <xsl:template match="Quantity">
    <xsl:variable name="supplier-code" select="parent::Item/suppliercode"/>
    <xsl:copy>
      <xsl:value-of select="sum(ancestor::Afile/Item[suppliercode = $supplier-code]/Quantity)"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

产量

<A>
   <target>
      <Item>
         <suppliercode>1</suppliercode>
         <PackNumber>1234</PackNumber>
         <Quantity>20</Quantity>
      </Item>
      <Item>
         <suppliercode>2</suppliercode>
         <PackNumber>567</PackNumber>
         <Quantity>3</Quantity>
      </Item>
      <Item>
         <suppliercode>1</suppliercode>
         <PackNumber>567</PackNumber>
         <Quantity>20</Quantity>
      </Item>
      <Item>
         <suppliercode>3</suppliercode>
         <PackNumber>126</PackNumber>
         <Quantity>11</Quantity>
      </Item>
      <Item>
         <suppliercode>4</suppliercode>
         <PackNumber>876</PackNumber>
         <Quantity>32</Quantity>
      </Item>
   </target>
</A>

更新为了把总到一个变量在使用它之前,你可以替换这个最后的模板

  <xsl:template match="Quantity">
    <xsl:variable name="supplier-code" select="parent::Item/suppliercode"/>
    <xsl:variable name="total" select="sum(ancestor::Afile/Item[suppliercode = $supplier-code]/Quantity)"/>
    <xsl:copy>
      <xsl:value-of select="$total"/>
    </xsl:copy>
  </xsl:template>

这台价值$total的数量与同suppplier代码的总和。



Answer 2:

这种高效短(使用键)转换:

<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="kQuantityBySupplier" match="Quantity" use="../suppliercode"/>

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

 <xsl:template match="/*">
  <A>
    <target>
      <xsl:apply-templates select="*/node()"/>
    </target>
  </A>
 </xsl:template>

 <xsl:template match="Quantity/text()">
  <xsl:value-of select="sum(key('kQuantityBySupplier', ../../suppliercode))"/>
 </xsl:template>
</xsl:stylesheet>

当施加在提供的XML文档:

<Move-Afile>
  <Afile>
    <Item>
    <suppliercode>1</suppliercode>
      <PackNumber>1234</PackNumber>
      <Quantity>12</Quantity>
    </Item>
    <Item>
    <suppliercode>2</suppliercode>
      <PackNumber>567</PackNumber>
      <Quantity>3</Quantity>
    </Item>
    <Item>
    <suppliercode>1</suppliercode>
      <PackNumber>567</PackNumber>
      <Quantity>8</Quantity>
    </Item>
    <Item>
    <suppliercode>3</suppliercode>
      <PackNumber>126</PackNumber>
      <Quantity>11</Quantity>
    </Item>
    <Item>
    <suppliercode>4</suppliercode>
      <PackNumber>876</PackNumber>
      <Quantity>32</Quantity>
    </Item>
  </Afile>
</Move-Afile>

产生想要的,正确的结果

<A>
   <target>
      <Item>
         <suppliercode>1</suppliercode>
         <PackNumber>1234</PackNumber>
         <Quantity>20</Quantity>
      </Item>
      <Item>
         <suppliercode>2</suppliercode>
         <PackNumber>567</PackNumber>
         <Quantity>3</Quantity>
      </Item>
      <Item>
         <suppliercode>1</suppliercode>
         <PackNumber>567</PackNumber>
         <Quantity>20</Quantity>
      </Item>
      <Item>
         <suppliercode>3</suppliercode>
         <PackNumber>126</PackNumber>
         <Quantity>11</Quantity>
      </Item>
      <Item>
         <suppliercode>4</suppliercode>
         <PackNumber>876</PackNumber>
         <Quantity>32</Quantity>
      </Item>
   </target>
</A>

请注意

这一转变的时间复杂度是线性的(O(N))。 这可以是数量级比反复扫描的所有元素以找到具有给定的那些更高效suppliercode -其具有使用二次(O(N ^ 2))的时间复杂度。


更新

的OP指定了新的要求,即总和或单个数量的变量被捕获:

只需修改此

 <xsl:template match="Quantity/text()">
  <xsl:value-of select="sum(key('kQuantityBySupplier', ../../suppliercode))"/>
 </xsl:template>

这个

 <xsl:template match="Quantity/text()">
  <xsl:variable name="vSum" select="sum(key('kQuantityBySupplier', ../../suppliercode))"/>
  <xsl:value-of select="$vSum"/>
 </xsl:template>


文章来源: Perform SUM operation in XSLT
标签: xslt