在 XSLT 中,如何计算给定属性值的每个不同值出现在输入 XML 中的次数?
Posted
技术标签:
【中文标题】在 XSLT 中,如何计算给定属性值的每个不同值出现在输入 XML 中的次数?【英文标题】:In XSLT, how do I count the number of times each distinct-value of a given attribute value appears in my input XML? 【发布时间】:2021-12-27 06:02:50 【问题描述】:假设我有一个 XML 剧本:
<speech><speaker name="Bob">BOB</speaker> Hey Jim!</speech>
<speech><speaker name="Jim">JIM</speaker> Hey Bob!</speech>
<speech><speaker name="Bob">BOB</speaker> How's Ethel?</speech>
我想使用 XSLT 在 html 表格中创建一个演讲者的不同值列表,以及每个演讲者的发言次数,如下所示:
<table>
<tr>
<th>Speaker</th>
<th>Frequency</th>
</tr>
<tr>
<td>Bob</td>
<td>2</td>
</tr>
<tr>
<td>Jim</td>
<td>1</td>
</tr> </table>
这是我的模板规则:
<xsl:template match="/">
<html>
<head>Speaker analysis</head>
<body>
<h1>Table of speech frequency</h1>
<table>
<tr><th>Speaker</th><th>Frequency</th></tr>
<xsl:for-each select="distinct-values(//speaker/@name)">
<tr><td><xsl:value-of select="."/></td>
<td><xsl:value-of select="count(../speech[speaker[@name='.']])"/></td></tr>
</xsl:for-each>
</table>
</body></html>
</xsl:template>
问题在这一行:
<td><xsl:value-of select="count(../speech[speaker[@name='.']])"/></td>
我真正想告诉它做的是“对于在这个 for 循环中标识的 @name 的给定不同值,计算它在整个文档中出现的次数”。所以我认为我真的需要从该属性值爬回祖先::轴来计算包含它的或元素。但是 oXygen 会给出错误信息。
肯定有办法做到这一点?
【问题讨论】:
【参考方案1】:这是分组的一个案例,而不是distinct-values:
<xsl:for-each-group select="//speaker" group-by="@name">
<tr>
<td>
<xsl:value-of select="@name"/>
</td>
<td>
<xsl:value-of select="count(current-group())"/>
</td>
</tr>
</xsl:for-each-group>
需要 XSLT 2.0 或更高版本。
附:要按照您开始的方式执行此操作,您需要通过name
定义一个匹配speaker
的key,然后计算key()
函数返回的序列。
另请注意,distinct-values()
函数返回不属于输入树的独立值序列;这些值没有祖先。
【讨论】:
成功了——谢谢!我不熟悉分组程序。我将不得不阅读它。以上是关于在 XSLT 中,如何计算给定属性值的每个不同值出现在输入 XML 中的次数?的主要内容,如果未能解决你的问题,请参考以下文章
XSLT 将具有父节点的节点移动到具有给定属性的每个父节点的兄弟节点中