问题:
我有一个XML列表项,我想显示一个包含其名称和属性的表。这是相当简单的,除了一些项目的属性是其他项目的总和。在以下示例中,我想显示食物名称和总卡路里。有些物品具有“卡路里”属性;其他人有一份成分清单,总卡路里应该是该清单中每个项目的卡路里总和。
对于含有其他聚合食品的集合食品不起作用的解决方案我没问题。我被限制为xsl 1.0。
<?xml version="1.0" encoding="ISO-8859-1"?>
<FoodList>
<SimpleFood name="Banana" calories="50"/>
<SimpleFood name="IceCream" calories="100"/>
<AggregateFood name="BananaSplit">
<IngredientList>
<Ingredient typeRef="Banana"/>
<Ingredient typeRef="IceCream"/>
<Ingredient typeRef="IceCream"/>
</IngredientList>
</AggregateFood>
</FoodList>
这是基本样式表:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:variable name="foods" select="FoodList/*"/>
<xsl:for-each select="$foods">
<tr>
<td>
<xsl:value-of select="@name"/>
</td>
<td>
<xsl:choose>
<xsl:when test="local-name()='SimpleFood'">
<xsl:value-of select="@calories"/>
</xsl:when>
<xsl:when test="local-name()='AggregateFood'">
<!-- -->
<!-- YOUR AWESOME CODE GOES HERE! -->
<!-- -->
</xsl:when>
</xsl:choose>
</td>
</tr>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
这是我想看到的输出:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<body>
<tr>
<td>Banana</td>
<td>50</td>
</tr>
<tr>
<td>IceCream</td>
<td>100</td>
</tr>
<tr>
<td>BananaSplit</td>
<td>250</td>
</tr>
</body>
</html>
ATTEMPTS:
<xsl:value-of select="sum($foods/*[@name=current()/IngredientList/Ingredient/@typeRef]/@calories)"/>
这不仅不起作用(返回0卡路里),但是找到与成分列表中的成分相匹配的每个元素的想法是有缺陷的,因为它会单独计算重复的冰淇淋成分并返回150卡路里而不是正确的250(如果有人能够向我展示这个版本的工作版本,那将是很酷的,为了个人的好奇心)。
另一次尝试:
<xsl:variable name="ingredients">
<xsl:for-each select="IngredientList/Ingredient">
<xsl:element name="Ingredient">
<xsl:attribute name="calories">
<xsl:value-of select="$foods/x:*[@name=current()/@typeRef]"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="sum($ingredients/@calories)"/>
与copy-element相同的是:
<xsl:variable name="ingredients">
<xsl:for-each select="IngredientList/Ingredient">
<xsl:copy-of select="$foods/x:*[@name=current()/@typeRef]"/>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="sum($ingredients/@calories)"/>
上述两项工作都没有:(我想将它们作为建议发布,但要让球滚动;也许你可以找到一个简单的错误。
我已经格式化了示例代码,以便您可以通过在线xsl转换器传递它,例如在此处找到的:http://www.freeformatter.com/xsl-transformer.html。除非我可以使用这样的工具获得所需的输出,否则我可能不会“接受”答案。
谢谢!
答案 0 :(得分:1)
使用模板,密钥和exsl:node-set
我写的
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl">
<xsl:key name="by-name" match="SimpleFood" use="@name"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="FoodList">
<table>
<thead>
<tr>
<th>Name</th>
<th>Calories</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates/>
</tbody>
</table>
</xsl:template>
<xsl:template match="SimpleFood">
<tr>
<td><xsl:value-of select="@name"/></td>
<td><xsl:value-of select="@calories"/></td>
</tr>
</xsl:template>
<xsl:template match="AggregateFood">
<tr>
<td><xsl:value-of select="@name"/></td>
<td>
<xsl:variable name="ing-cals">
<xsl:for-each select="IngredientList/Ingredient">
<cal><xsl:value-of select="key('by-name', @typeRef)/@calories"/></cal>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="sum(exsl:node-set($ing-cals)/cal)"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
输出
<html>
<body>
<table>
<thead>
<tr>
<th>Name</th>
<th>Calories</th>
</tr>
</thead>
<tbody>
<tr>
<td>Banana</td>
<td>50</td>
</tr>
<tr>
<td>IceCream</td>
<td>100</td>
</tr>
<tr>
<td>BananaSplit</td>
<td>250</td>
</tr>
</tbody>
</table>
</body>
</html>