如何计算所需的结果

时间:2011-06-13 11:12:42

标签: xslt

请帮助解决这个xml:

<document>
    <sheet id="0" name="Sheet1">
    <line id="0">
        <field id="0"><![CDATA[Calculate]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[Quantity]]></field>
        <field id="1"><![CDATA[Value]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[3]]></field>
        <field id="1"><![CDATA[2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[2]]></field>
        <field id="1"><![CDATA[7]]></field>
    </line>
    <line id="4">
        <field id="0"></field>
        <field id="1"></field>
    </line>
    </sheet>
</document>

在将此字段与字段[@ id = 0]相乘之前,我需要得到字段的总和[@ id = 1]。行[@ id = 4]为空,因此应该有条件消除这一行。

正确的结果应该是:

<document>
    <id>Calculate</id>
    <line>
    <sum>20</sum>
    </line>
</document>

1 个答案:

答案 0 :(得分:2)

这是一个XSLT 2.0解决方案,可以使用Saxon 9XQSharpAltovaXML等XSLT 2.0处理器运行:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs"
  version="2.0">

  <xsl:output indent="yes"/>

  <xsl:template match="document">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="sheet">
    <id><xsl:value-of select="line[@id = 0]/field"/></id>
    <line>
      <sum>
        <xsl:value-of select="sum(line[field[@id = 1] castable as xs:double and field[@id = 0] castable as xs:double]/(field[@id = 1] * field[@id = 0]))"/>
      </sum>
    </line>
  </xsl:template>

</xsl:stylesheet>

[edit]我正在添加一个带有命名递归模板的XSLT 1.0样式表:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:output indent="yes"/>

  <xsl:template match="document">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="sum">
    <xsl:param name="lines"/>
    <xsl:param name="total" select="0"/>
    <xsl:choose>
      <xsl:when test="not($lines)">
        <xsl:value-of select="$total"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="sum">
          <xsl:with-param name="lines" select="$lines[position() &gt; 1]"/>
          <xsl:with-param name="total" select="$total + $lines[1]/field[@id = 1] * $lines[1]/field[@id = 0]"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>        

  <xsl:template match="sheet">
    <id><xsl:value-of select="line[@id = 0]/field"/></id>
    <line>
      <sum>
        <xsl:call-template name="sum">
          <xsl:with-param name="lines" 
            select="line[number(field[@id = 1]) = number(field[@id = 1]) 
                         and number(field[@id = 0]) = number(field[@id = 0])]"/>
         </xsl:call-template>
    </sum>
    </line>
  </xsl:template>

</xsl:stylesheet>