我有一个包含关系列表的xml文件。样品:
<document>
<list>
<rel>
<item1>1</item1>
<item2>6</item2>
</rel>
<rel>
<item1>2</item1>
<item2>3</item2>
</rel>
<rel>
<item1>3</item1>
<item2>5</item2>
</rel>
<rel>
<item1>3</item1>
<item2>6</item2>
</rel>
<rel>
<item1>2</item1>
<item2>8</item2>
</rel>
<rel>
<item1>2</item1>
<item2>7</item2>
</rel>
</list>
</document>
item1表示项目的ID。
我想打印出第1个id列表,按照第1项中出现次数的降序排序。所以我需要计算每个id出现在item1中的次数,然后按降序对它们进行排序。最后,我需要打印第一个第n个ID。
预期答案:
2
3
我正在使用的xlst代码是:
<body>
<ul>
<xsl:for-each select="document/list/rel">
<xsl:sort select="count(item1)" order="descending"/>
<xsl:if test="position() <= $nthIDs">
<li><xsl:value-of select="item1"/></li>
</xsl:if>
</xsl:for-each>
</ul>
</body>
代码返回的内容:
1
2
它所做的就是打印第n个第一个item1而不进行任何排序,因此它不能按预期工作。我的代码主要基于:xslt sorting by child element count ,但那个使用直接的孩子,我需要孙子节点。我找到了另一个链接:XSLT Sort grandchild nodes and pick the value of another grandchild 谈论孙子孙女,但我不完全明白这种方式是如何运作的。有人可以帮我理解第二个链接中使用的排序以及如何实现它吗?
我正在使用xslt 3.0,但2.0或1.0中的任何解决方案都非常受欢迎。
谢谢。
答案 0 :(得分:1)
您可以使用for-each-group
进行分组,然后计算组中的项目数并按其排序,如果需要,只输出多个组:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
expand-text="yes"
version="3.0">
<xsl:param name="number-of-groups" as="xs:integer" select="2"/>
<xsl:mode on-no-match="shallow-skip"/>
<xsl:output method="html" indent="yes" html-version="5"/>
<xsl:template match="/">
<html>
<head>
<title>Group and Sort</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="list">
<ul>
<xsl:for-each-group select="rel" group-by="item1">
<xsl:sort select="count(current-group())" order="descending"/>
<xsl:if test="position() le $number-of-groups">
<li>
item {item1}, count: {count(current-group())}
</li>
</xsl:if>
</xsl:for-each-group>
</ul>
</xsl:template>
</xsl:stylesheet>