XSLT 按孙子数量排序
XLST sort by grandchild count
我有一个包含关系列表的 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。
我想打印出第 n 个 ID 的列表,这些 ID 按它们在 item1 中出现的次数降序排列。所以我需要统计每个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>
密码是什么returns:
1
2
它所做的只是打印第 n 个第一项 item1 而不进行任何排序,因此它没有按预期工作。我的代码主要基于:xslt sorting by child element count
,但是那个使用直接子节点,我需要孙节点。我找到了另一个 link : XSLT Sort grandchild nodes and pick the value of another grandchild
那是关于孙子的,但我不完全理解那种方式是如何运作的。有人可以帮助我理解第二个 link 中使用的排序以及如何实现它吗?
我使用的是 xslt 3.0,但是 2.0 或 1.0 中的任何解决方案都非常受欢迎。
谢谢。
您可以使用 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>
我有一个包含关系列表的 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。
我想打印出第 n 个 ID 的列表,这些 ID 按它们在 item1 中出现的次数降序排列。所以我需要统计每个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>
密码是什么returns:
1
2
它所做的只是打印第 n 个第一项 item1 而不进行任何排序,因此它没有按预期工作。我的代码主要基于:xslt sorting by child element count ,但是那个使用直接子节点,我需要孙节点。我找到了另一个 link : XSLT Sort grandchild nodes and pick the value of another grandchild 那是关于孙子的,但我不完全理解那种方式是如何运作的。有人可以帮助我理解第二个 link 中使用的排序以及如何实现它吗?
我使用的是 xslt 3.0,但是 2.0 或 1.0 中的任何解决方案都非常受欢迎。
谢谢。
您可以使用 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>