目前在XSLT中收到NaN错误。 我想获得所有产品及其订购数量的总价值或收入。
XML:
<customers>
<customer>
<customername>John</customername>
</customer>
<invoices>
<invoice>
<invoicenumber>01</invoicenumber>
<products>
<product>
<productname>candy bar</productname>
<productamount>6</productamount
<productcost>2</productcost>
</product>
</products>
</invoice>
<invoice>
<invoicenumber>02</invoicenumber>
<products>
<product>
<productname>choco bar</productname>
<productamount>3</productamount
<productcost>1</productcost>
</product>
</products>
</invoice>
</invoices>
<customer>
<customername>Fritz</customername>
</customer>
<invoices>
<invoice>
<invoicenumber>01</invoicenumber>
<products>
<product>
<productname>Soda</productname>
<productamount>3</productamount
<productcost>2</productcost>
</product>
</products>
</invoice>
<invoice>
<invoicenumber>02</invoicenumber>
<products>
<product>
<productname>lollipop</productname>
<productamount>5</productamount
<productcost>1</productcost>
</product>
</products>
</invoice>
</invoices>
我试图改编递归模板。
XSL:
Total:
<xsl:call-template name="sumProducts">
<xsl:with-param name="pNodes" select="customers/customer/invoices/invoice/products"/>
<xsl:with-param name="pName1" select="././././././productamount"/>
<xsl:with-param name="pName2" select="././././././productcost"/>
</xsl:call-template>
<xsl:template name="sumProducts">
<xsl:param name="pNodes"/>
<xsl:param name="pName1"/>
<xsl:param name="pName2"/>
<xsl:param name="pAccum" select="0"/>
<xsl:choose>
<xsl:when test="not($pNodes)">
<xsl:value-of select="$pAccum"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="sumProducts">
<xsl:with-param name="pNodes" select="$pNodes[position() > 1]"/>
<xsl:with-param name="pName1" select="$pName1"/>
<xsl:with-param name="pName2" select="$pName2"/>
<xsl:with-param name="pAccum" select="$pAccum + $pNodes[1]/*[name()=$pName1]
* pNodes[1]/*[name()=$pName2]"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
期望的结果将是Total = 26
答案 0 :(得分:2)
我可以看到您的XSLT存在一些问题。首先, pNodes 参数的设置不正确
<xsl:with-param name="pNodes" select="customers/customer/invoices/invoice/products"/>
从查看XML,需要如下
<xsl:with-param name="pNodes" select="customers/invoices/invoice/products/product"/>
即。 发票元素不在您示例中的客户元素中,此外您还想要对各个产品元素求和。
接下来,正如Ian Roberts所提到的, pName1 和 pName2 看起来应该被设置为元素名称。目前,您只需将它们设置为这些元素首次出现的值。
<xsl:with-param name="pName1" select="'productamount'"/>
<xsl:with-param name="pName2" select="'productcost'"/>
最后, pAccum 参数的设置错误。你现在正在这样做......
<xsl:with-param name="pAccum"
select="$pAccum + $pNodes[1]/*[name()=$pName1] * pNodes[1]/*[name()=$pName2]"/>
但是您在第二个 pNodes 变量之前错过了$。它应该是这样的:
<xsl:with-param name="pAccum"
select="$pAccum + $pNodes[1]/*[name()=$pName1] * $pNodes[1]/*[name()=$pName2]"/>
这是完整的XSLT,它应该给你26
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:call-template name="sumProducts">
<xsl:with-param name="pNodes" select="customers/invoices/invoice/products/product"/>
<xsl:with-param name="pName1" select="'productamount'"/>
<xsl:with-param name="pName2" select="'productcost'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="sumProducts">
<xsl:param name="pNodes"/>
<xsl:param name="pName1"/>
<xsl:param name="pName2"/>
<xsl:param name="pAccum" select="0"/>
<xsl:choose>
<xsl:when test="not($pNodes)">
<xsl:value-of select="$pAccum"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="sumProducts">
<xsl:with-param name="pNodes" select="$pNodes[position() > 1]"/>
<xsl:with-param name="pName1" select="$pName1"/>
<xsl:with-param name="pName2" select="$pName2"/>
<xsl:with-param name="pAccum" select="$pAccum + $pNodes[1]/*[name()=$pName1] * $pNodes[1]/*[name()=$pName2]"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
您的递归模板看起来没问题,我认为问题在于您的初始pName1
和pName2
参数值。尝试
<xsl:with-param name="pName1" select="'productamount'"/>
<xsl:with-param name="pName2" select="'productcost'"/>
您的模板希望这些参数是包含相关元素的名称的字符串,这就是为什么您需要双引号select
属性中的单引号。