I want perform sum of product of two elements at d

2019-09-20 14:38发布

I tried for following code but its not working. I have taken one string and write XSLT in it and load it XslCompiledTransform object.

 <xsl:sequence select=
        "sum(//Item/(cost * related_id/Item/quantity))"/>

Source XML:

<AML>
  <Item>
    <cost>
      40
    </cost>
    <related_id>
      <Item>
        <quantity>2</quantity>
      </Item>
    </related_id>
  </Item>
  <Item>
    <cost>
      50
    </cost>
    <related_id>
      <Item>
        <quantity>10</quantity>
      </Item>
    </related_id>
  </Item>
</AML>

1条回答
看我几分像从前
2楼-- · 2019-09-20 15:12

As I said in the comments, xsl:sequence and that XPath syntax you're trying to use aren't available in XSLT 1.0 (which XslCompiledTransform uses), but you can achieve a sum of formulas by using a recursive template:

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

  <xsl:template match="/">
    <xsl:call-template name="SumSet">
      <xsl:with-param name="items" select="/*/Item" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="SumSet">
    <xsl:param name="items" />

    <xsl:if test="$items">
      <xsl:variable name="currentValue">
        <xsl:apply-templates select="$items[1]" />
      </xsl:variable>
      <xsl:variable name="remainderSum">
        <xsl:call-template name="SumSet">
          <xsl:with-param name="items" select="$items[position() > 1]" />
        </xsl:call-template>
      </xsl:variable>

      <xsl:value-of select="$currentValue + $remainderSum"/>
    </xsl:if>
    <xsl:if test="not($items)">0</xsl:if>
  </xsl:template>

  <xsl:template match="Item">
    <xsl:value-of select="cost * related_id/Item/quantity"/>
  </xsl:template>
</xsl:stylesheet>

When this is run on your input XML, the result is:

580

That would be the generic approach, but since you've mentioned that you're using XslCompiledTransform, you can use msxsl:node-set() to simplify this task a bit:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt">
  <xsl:output method="text" indent="yes"/>

  <xsl:template match="/">
    <xsl:variable name="values">
      <xsl:apply-templates select="/*/Item" />
    </xsl:variable>

    <xsl:value-of select="sum(msxsl:node-set($values)/*)"/>
  </xsl:template>

  <xsl:template match="Item">
    <itemValue>
      <xsl:value-of select="cost * related_id/Item/quantity"/>
    </itemValue>
  </xsl:template>
</xsl:stylesheet>

This also produces the value 580 when run on your input XML.

查看更多
登录 后发表回答