【发布时间】:2011-03-19 19:37:37
【问题描述】:
我想在标题下按元素名称(然后按相同的属性名称)对来自 XPath 的结果进行分类。注意:XML 数据可能不一致,某些同名元素可能具有不同的属性,因此它们需要不同的标题。
我似乎无法用语言写出我的问题,所以最好举个例子..
XML:
<pets>
<dog name="Frank" cute="yes" color"brown" type="Lab"/>
<cat name="Fluffy" cute="yes" color="brown"/>
<cat name="Lucy" cute="no" color="brown"/>
<dog name="Spot" cute="no" color="brown"/>
<dog name="Rover" cute="yes" color="brown"/>
<dog name="Rupert" cute="yes" color="beige" type="Pug"/>
<cat name="Simba" cute="yes" color="grey"/>
<cat name="Princess" color="brown"/>
</pets>
XPath:
//*[@color='brown']
输出应该是什么样子(不同元素的标题不同):
ElementName Color Cute Name Type
Dog Brown Yes Frank Lab
ElementName Color Cute Name
Dog Brown No Spot
Dog Brown Yes Rover
ElementName Color Cute Name
Cat Brown Yes Fluffy
Cat Brown No Lucy
ElementName Color Name
Cat Brown Princess
我目前拥有的 XSL(简化了!):
<xsl:apply-templates select="//*[@color='brown']" mode="result">
<xsl:sort select="name()" order="ascending"/>
</xsl:apply-templates>
<xsl:template match="@*|node()" mode="result">
<tr>
<th align="left">Element</th>
<xsl:for-each select="@*">
<xsl:sort select="name()" order="ascending"/>
<th align="left">
<xsl:value-of select="name()"/>
</th>
</xsl:for-each>
</tr>
<tr>
<td align="left">
<xsl:value-of select="name()"/>
</td>
<xsl:for-each select="@*">
<xsl:sort select="name()" order="ascending"/>
<td align="left">
<xsl:value-of select="."/>
</td>
</xsl:for-each>
</tr>
</xsl:template>
上面的 XSL 以我想要的方式正确地对它们进行排序.. 但现在我需要某种检查来查看哪些元素具有相同的名称,然后如果它们具有相同的名称,它们是否具有相同的属性。完成此检查后,我可以将一般“标题”放在具有匹配元素名称和属性的记录集上方。
我想我可以使用 xsl:choose xsl:when 并进行一些测试。我在想(在正确排序之后):
If element name != previous element name
create headings
Else if all attributes != all previous element's attributes
create headings
我想我最大的问题是,我不知道如何检查以前返回的数据集是什么...有人可以告诉我该怎么做吗?
或者如果我接近这个错误.. 引导我找到更好的解决方案?
希望一切都有意义!如果您需要澄清,请告诉我!
提前感谢您的耐心和回复! :)
【问题讨论】:
-
好问题! (+1)。请参阅我的答案,了解通用且高效的 XSLT 1.0 解决方案,该解决方案适用于元素和属性的任何可能组合。 :)
标签: xslt sorting xpath grouping