我有一些类似的XML:
farms myfarm
animals
pigs
name Oinker
cats
name Willy
farms myfarm2
animals
pigs
name Cheeky
cats
name Fuzz
farms myfarm3
animals
pigs
name Curly
cats
name Elvis
每只动物下面都有很多标签。在一般情况下,动物可能因农场而异,但就我而言,它们并非如此。所有农场都有相同的动物。因此,我可以从任何农场获得一群动物(猫和猪),尽管更通用的解决方案是聚集来自所有农场的动物。
我想生成一个相反结构的报告,如:
ANIMAL pigs
myfarm Oinker
myfarm2 Cheeky
myfarm3 Curly
ANIMAL cats
myfarm Willy
myfarm2 Fuzz
myfarm3 Elvis
所以在XML中,FARMS包含ANIMALS,但在报告中,ANIMALS包含FARMS。
我做了几次尝试,但最近的尝试是这样的:
xsl:for-each select="/farms[1]/animals"
xsl:variable name="animali" select="."
xsl:for-each select="farms"
.
.
td xsl select="$animali/name" /td
这实际上接近一个解决方案,因为如果我有3个农场,每个有2只动物,我最终得到2个表,每个3行。完美!
问题是你可能发现的,只考虑了Farm#1。所以我最终得到了:
ANIMAL pigs
myfarm Oinker
myfarm2 Oinker
myfarm3 Oinker
ANIMAL cats
myfarm Willie
myfarm2 Willie
myfarm3 Willie
我想也许我需要迭代FARMS,然后是动物,然后是农场?如果这有道理?
非常欢迎提供建议。
答案 0 :(得分:1)
由于您使用的是XSLT 1.0,因此您需要使用Muenchian Grouping。
假设您的XML与我在下面猜到的一样(如果您使用示例XML更新问题,我将更新此答案),xsl:key应使用animals
的子元素名称。< / p>
XML输入
<farms>
<farm id="myfarm">
<animals>
<pigs>
<name>Oinker</name>
</pigs>
<cats>
<name>Willy</name>
</cats>
</animals>
</farm>
<farm id="myfarm2">
<animals>
<pigs>
<name>Cheeky</name>
</pigs>
<cats>
<name>Fuzz</name>
</cats>
</animals>
</farm>
<farm id="myfarm3">
<animals>
<pigs>
<name>Curly</name>
</pigs>
<cats>
<name>Elvis</name>
</cats>
</animals>
</farm>
</farms>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="animals" match="animals/*" use="local-name()"/>
<xsl:template match="/">
<html>
<body>
<xsl:for-each
select="farms/farm/animals/*[count(.|key('animals',local-name())[1])=1]">
<table>
<thead>
<tr>
<th>ANIMAL</th>
<th><xsl:value-of select="local-name()"/></th>
</tr>
</thead>
<tbody>
<xsl:for-each select="key('animals',local-name())">
<xsl:sort select="ancestor::farm/@id" data-type="text"/>
<tr>
<td><xsl:value-of select="ancestor::farm/@id"/></td>
<td><xsl:value-of select="name"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
输出(点击“运行代码段”查看呈现的HTML)
<html>
<body>
<table>
<thead>
<tr>
<th>ANIMAL</th>
<th>pigs</th>
</tr>
</thead>
<tbody>
<tr>
<td>myfarm</td>
<td>Oinker</td>
</tr>
<tr>
<td>myfarm2</td>
<td>Cheeky</td>
</tr>
<tr>
<td>myfarm3</td>
<td>Curly</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>ANIMAL</th>
<th>cats</th>
</tr>
</thead>
<tbody>
<tr>
<td>myfarm</td>
<td>Willy</td>
</tr>
<tr>
<td>myfarm2</td>
<td>Fuzz</td>
</tr>
<tr>
<td>myfarm3</td>
<td>Elvis</td>
</tr>
</tbody>
</table>
</body>
</html>