How do i get total cost of all the items in for-each loop?
如何获得for-each循环中所有项目的总成本?
<?xml version="1.0" encoding="utf-8" ?>
<Characters>
<Character ID="1" Name="Simmo">
<Inventory MaxSlots="20">
<Item ID="1" Name="Gold" Cost="1">
<Count>100</Count>
</Item>
<Item ID="1" Name="hat" Cost="10">
<Count>1</Count>
</Item>
<Item ID="2" Name="stick" Cost="15">
<Count>2</Count>
</Item>
</Inventory>
</Character>
</Characters>
For example 1*100+10*1+15*2=140
例如1 * 100 + 10 * 1 + 15 * 2 = 140
My unfinished xsl solution:
我未完成的xsl解决方案:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
>
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>xsl file</title>
</head>
<body>
<ul>
<xsl:for-each select="/Characters/Character">
<li>
Character name: <xsl:value-of select="@Name"/>
<br/>
<xsl:for-each select="Inventory/Item">
<xsl:variable name="cos" select="@Cost"/>
<xsl:variable name="cou" select="Count"/>
<xsl:variable name="kor" select="$cos*$cou"/>
Total cost:<xsl:value-of select="$kor"/>
<br/>
</xsl:for-each>
<br />
</li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Current output:
Character name: Simmo Total cost:100 Total cost:10 Total cost:30
字符名称:Simmo总费用:100总费用:10总费用:30
But how to get Character name: Simmo Total cost:140
但如何获得角色名称:Simmo总费用:140
2 个解决方案
#1
10
Three possibilities:
(1) Move to XSLT 2.0 and write
(1)转到XSLT 2.0并编写
Character name: <xsl:value-of select="@Name"/>
<br/>
Total cost: <xsl:value-of select="
sum(for $i in Inventory/Item return $i/@Cost * $i/Count)
"/>
(2) In XSLT 1.0, use the EXSLT node-set extension described in some detail in the related question already pointed to to (a) make a set of nodes containing the product of @Cost and Count, and (b) sum them.
(2)在XSLT 1.0中,使用已经指向的相关问题中详细描述的EXSLT节点集扩展(a)创建一组包含@Cost和Count的乘积的节点,以及(b)求和它们。
(3) Write a recursive named template to loop through the set of items, calculating a running total. That would look something like this (not tested):
(3)编写递归命名模板以遍历项集,计算运行总计。这看起来像这样(未经测试):
<xsl:template match="/">
... some of your code omitted here ...
<xsl:for-each select="/Characters/Character">
<li>
Character name: <xsl:value-of select="@Name"/>
<br/>
<xsl:call-template name="sum-items">
<xsl:with-param name="item"
select="Inventory/Item[1]"/>
<xsl:with-param name="accumulator"
select="0"/>
</xsl:call-template>
<br />
</li>
</xsl:for-each>
...
</xsl:template>
<xsl:template name="sum-items">
<xsl:param name="item"/>
<xsl:param name="accumulator"/>
<xsl:choose>
<xsl:when test="not($item)">
<!--* done, return result *-->
Total cost: <xsl:value-of select="$accumulator"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="acc"
select="$accumulator + ($item/@Cost * $item/Count)"/>
<xsl:call-template name="sum-items">
<xsl:with-param name="item"
select="$item/following-sibling::item[1]"/>
<xsl:with-param name="accumulator" select="$acc"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:when>
</xsl:template>
#2
2
Per comment above:
以上评论:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="msxsl">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>xsl file</title>
</head>
<body>
<ul>
<xsl:for-each select="/Characters/Character">
<li>
<xsl:text>Character name: </xsl:text>
<xsl:value-of select="@Name"/>
<br/>
<xsl:for-each select="Inventory/Item">
<xsl:variable name="cos" select="@Cost"/>
<xsl:variable name="cou" select="Count"/>
<xsl:variable name="kor" select="$cos*$cou"/>
<xsl:text>line cost:</xsl:text>
<xsl:value-of select="$kor"/>
<xsl:text> for </xsl:text>
<xsl:value-of select="@Name"/>
<br/>
</xsl:for-each>
<xsl:variable name="lines">
<xsl:for-each select="Inventory/Item">
<cost>
<xsl:value-of select="Count * @Cost"/>
</cost>
</xsl:for-each>
</xsl:variable>
<xsl:text>Total cost:</xsl:text>
<xsl:value-of select="sum(exsl:node-set($lines)/cost)"/>
<br/>
</li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
#1
10
Three possibilities:
(1) Move to XSLT 2.0 and write
(1)转到XSLT 2.0并编写
Character name: <xsl:value-of select="@Name"/>
<br/>
Total cost: <xsl:value-of select="
sum(for $i in Inventory/Item return $i/@Cost * $i/Count)
"/>
(2) In XSLT 1.0, use the EXSLT node-set extension described in some detail in the related question already pointed to to (a) make a set of nodes containing the product of @Cost and Count, and (b) sum them.
(2)在XSLT 1.0中,使用已经指向的相关问题中详细描述的EXSLT节点集扩展(a)创建一组包含@Cost和Count的乘积的节点,以及(b)求和它们。
(3) Write a recursive named template to loop through the set of items, calculating a running total. That would look something like this (not tested):
(3)编写递归命名模板以遍历项集,计算运行总计。这看起来像这样(未经测试):
<xsl:template match="/">
... some of your code omitted here ...
<xsl:for-each select="/Characters/Character">
<li>
Character name: <xsl:value-of select="@Name"/>
<br/>
<xsl:call-template name="sum-items">
<xsl:with-param name="item"
select="Inventory/Item[1]"/>
<xsl:with-param name="accumulator"
select="0"/>
</xsl:call-template>
<br />
</li>
</xsl:for-each>
...
</xsl:template>
<xsl:template name="sum-items">
<xsl:param name="item"/>
<xsl:param name="accumulator"/>
<xsl:choose>
<xsl:when test="not($item)">
<!--* done, return result *-->
Total cost: <xsl:value-of select="$accumulator"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="acc"
select="$accumulator + ($item/@Cost * $item/Count)"/>
<xsl:call-template name="sum-items">
<xsl:with-param name="item"
select="$item/following-sibling::item[1]"/>
<xsl:with-param name="accumulator" select="$acc"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:when>
</xsl:template>
#2
2
Per comment above:
以上评论:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="msxsl">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>xsl file</title>
</head>
<body>
<ul>
<xsl:for-each select="/Characters/Character">
<li>
<xsl:text>Character name: </xsl:text>
<xsl:value-of select="@Name"/>
<br/>
<xsl:for-each select="Inventory/Item">
<xsl:variable name="cos" select="@Cost"/>
<xsl:variable name="cou" select="Count"/>
<xsl:variable name="kor" select="$cos*$cou"/>
<xsl:text>line cost:</xsl:text>
<xsl:value-of select="$kor"/>
<xsl:text> for </xsl:text>
<xsl:value-of select="@Name"/>
<br/>
</xsl:for-each>
<xsl:variable name="lines">
<xsl:for-each select="Inventory/Item">
<cost>
<xsl:value-of select="Count * @Cost"/>
</cost>
</xsl:for-each>
</xsl:variable>
<xsl:text>Total cost:</xsl:text>
<xsl:value-of select="sum(exsl:node-set($lines)/cost)"/>
<br/>
</li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>