Xml 每个需求的奇怪XSLT
我有一些XML类似于:Xml 每个需求的奇怪XSLT,xml,xslt,foreach,xslt-1.0,Xml,Xslt,Foreach,Xslt 1.0,我有一些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
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中,农场包含动物,但在报告中,动物包含农场
我已经做了几次尝试,但最近的一次尝试是:
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行。太好了
问题是,你可能已经发现了,只考虑了一个农场。因此,我最终得出以下结论:
ANIMAL pigs
myfarm Oinker
myfarm2 Oinker
myfarm3 Oinker
ANIMAL cats
myfarm Willie
myfarm2 Willie
myfarm3 Willie
我在想也许我需要重复农场,然后是动物,然后是农场?这有意义吗?
建议是非常受欢迎的。因为您使用的是XSLT1.0,所以您需要使用 假设您的XML与我在下面猜测的类似(如果您使用示例XML更新问题,我将更新此答案),xsl:key应该使用
动物的子元素名
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>
奥克
威利
厚颜无耻的
绒毛
卷曲的
埃尔维斯
XSLT1.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)
动物
猪
我的农场
奥克
我的农场2
厚颜无耻的
我的农场3
卷曲的
动物
猫
我的农场
威利
我的农场2
绒毛
我的农场3
埃尔维斯
我想我现在有了一个可用的版本,但就像轮胎一样,“她不漂亮”。。。我在动物上循环(获取主表),然后在农场上循环(获取行),然后再循环动物(过滤掉不在此表中的动物)。我将内心的动物(听起来像禅,不是吗?)与外在的动物进行比较。如果匹配,则打印该行。很好,但没有达到我通常的优雅标准。。。从好的方面来说,我认为它可以聚合一般情况。XSLT的哪个版本?这是一个分组问题,根据您使用的XSLT版本,分组的处理方式通常有所不同。此外,如果问题中的输入被更新为XML而不是XML的树表示形式,这将非常有用。(输出也应该是您真正想要实现的内容(可能是HTML表?)。XSLT 1.0-我查看了分组等,但看起来不太有希望。我会加入更多XML风格的东西哇,谢谢,这很有帮助。我甚至不知道这是可能的。先生,我非常感谢您的回复!我的XML实际上是一个非常不同的例子——我只是用农场动物的例子来说明。你的解释很完美。我刚试过你的回答,看起来很完美。我对您正在使用的一些东西不太熟悉—模板、本地名称等,但您为我提供了一个学习XSLT的绝佳场所。再次感谢你,先生,你做了一件非常好的事情……也许你能描述一下这句话的意思?管道、钥匙和星号?xsl:for each select=“farms/farm/animals/*[count(.| key('animals',local-name())[1])=1]我在你参考的页面中看到了一些类似的代码。但没有真正解释。还在阅读-大量的理解!我像XSLT 101,这就像是研究生级别!顺便说一句,这是我正在处理的现实世界问题,不是家庭作业辅助。我现在唯一的课程是区块链。@Spyder-这是在计算两者之间的联盟n当前元素和键中的第一项。本质上,它只是选择键中的第一项。它也可以像select=“farms/farm/animals/*[generate-id()=generate-id(key('animals',local-name())[1])那样编写“
。链接到Jeni Tennison的网页上的MuniCn分组做了很好的解释它的工作。@ Syder--也请考虑通过点击旁边的复选标记接受这个答案。