2011-06-13 56 views
0

请与该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 = 1]前与现场[@ ID = 0]乘这个领域。行[@ id = 4]是空的,所以应该有条件消除这一行。

正确的结果应该是:

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

回答

2

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

<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> 

[编辑]我加入一个带有下面的命名递归模板的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> 
+0

对不起我没有注意到我被困在XSLT 1.0 – Petras 2011-06-13 11:54:58

+0

感谢answe。 – Petras 2011-06-14 07:43:53