XSL - sum multiplication of elements

前端 未结 2 1313
野性不改
野性不改 2021-01-14 00:40

I have a few items like this one:


    172
    42         


        
相关标签:
2条回答
  • In addition to the correct answer by Kirill:

    I. XPath 2.0 (XSLT 2.0) solution:

    Use this single XPath 2.0 expression from any language hosting XPath 2.0:

    sum(/*/*/(quantity*unit-price))
    

    Here is a complete example using XSLT 2.0 as the host of XPath 2.0:

    <xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="/">
      <xsl:sequence select="sum(/*/*/(quantity*unit-price))"/>
     </xsl:template>
    </xsl:stylesheet>
    

    when applied on the following XML document:

    <items>
        <item type="goods">
            <quantity unit="pcs">1</quantity>
            <unit-price currency="PLN">2</unit-price>
            <VAT>7</VAT>
        </item>
        <item type="goods">
            <quantity unit="pcs">10</quantity>
            <unit-price currency="PLN">20</unit-price>
            <VAT>7</VAT>
        </item>
        <item type="goods">
            <quantity unit="pcs">100</quantity>
            <unit-price currency="PLN">200</unit-price>
            <VAT>7</VAT>
        </item>
    </items>
    

    the wanted, correct result is produced:

    20202
    

    II. XSLT 1.0 solution using the transform-and-sum template/function of FXSL 1.x

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:f="http://fxsl.sf.net/"
    xmlns:func-transform="f f:func-transform"
    exclude-result-prefixes="xsl func-transform"
    >
       <xsl:import href="transform-and-sum.xsl"/>
    
       <!-- to be applied on testTransform-and-sum5.xml -->
    
       <xsl:output method="text"/>
    
       <func-transform:func-transform/>
    
        <xsl:template match="/">
          <xsl:call-template name="transform-and-sum">
            <xsl:with-param name="pFuncTransform" 
                            select="document('')/*/func-transform:*[1]"/>
            <xsl:with-param name="pList" select="/*/*"/>
          </xsl:call-template>
        </xsl:template>
    
        <xsl:template match="func-transform:*" mode="f:FXSL">
          <xsl:param name="arg1" select="0"/>
          <xsl:value-of select="$arg1/quantity * $arg1/unit-price "/>
        </xsl:template>
    </xsl:stylesheet>
    

    when this transformation is applied on the same XML document (above), the same correct result is produced:

    20202
    

    Do note: Using FXSL one doesn't need to implement explicit recursion "for the Nth time", the solution is compact and potential errors writing the recursion are eliminated altogether.

    As a whole the total development time, readability and flexibility are dramatically improved.

    0 讨论(0)
  • 2021-01-14 01:26

    XSLT:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
    
      <xsl:template match="/root">
        <xsl:text>sum:</xsl:text>
    
        <xsl:call-template name="sum">
          <xsl:with-param name="nodes" select="item"/>
        </xsl:call-template>
      </xsl:template>
    
      <xsl:template name="sum">
        <xsl:param name="nodes" />
        <xsl:param name="sum" select="0" />
    
        <xsl:variable name="current" select="$nodes[1]" />
    
        <xsl:if test="$current"> 
          <xsl:call-template name="sum">
            <xsl:with-param name="nodes" select="$nodes[position() &gt; 1]" />
            <xsl:with-param name="sum" select="$sum + $current/quantity * $current/unit-price" />
          </xsl:call-template>
        </xsl:if>
    
        <xsl:if test="not($current)">
          <xsl:value-of select="$sum" />
        </xsl:if>
    
      </xsl:template>
    
    </xsl:stylesheet>
    

    Input XML:

    <root>
      <item type="goods">
        <quantity unit="pcs">1</quantity>
        <unit-price currency="PLN">2</unit-price>
        <VAT>7</VAT>
      </item>
      <item type="goods">
        <quantity unit="pcs">10</quantity>
        <unit-price currency="PLN">20</unit-price>
        <VAT>7</VAT>
      </item>
      <item type="goods">
        <quantity unit="pcs">100</quantity>
        <unit-price currency="PLN">200</unit-price>
        <VAT>7</VAT>
      </item>
    </root>
    

    Output:

    sum:20202
    
    0 讨论(0)
提交回复
热议问题