我对这个关键功能有点困惑:
<xsl:for-each select="article[count(. | key('idkey', @id)[1]) = 1]>
有没有人可以简要解释这个 for-each 循环中发生的事情?
关键是:<xsl:key name="idkey" match="/newspapers/newspaper" use="@id"/>
@id 是报纸上的一个属性。
谢谢。
该表达式key('idkey', @id)[1]
选择 idkey 等于 @id 的第一个元素。
该表达式count(A|B) = 1
是一个疯狂的 XSLT 1.0 解决方法,用于测试 A 和 B 是否是同一个节点。(您还会看到人们generate-id(A)=generate-id(B)
为此使用。)
将这些放在一起,您将询问当前元素是否是文档中第一个具有特定 id 值的元素。
这是称为 Muenchian Grouping 的技术(在 XSLT 2.0 中变得多余)的基础。
代码有些可疑,因为密钥似乎与报纸 ID 匹配,而不是文章 ID。但也许它们在某种程度上是相关的。
在这个for-each
元素中
<xsl:for-each select="article[count(. | key('idkey', @id)[1]) = 1]">
将for-each
应用于每个 属性的第一个元素。 article
@id
该调用key('idkey', @id)
正在选择与当前article
元素具有相同@id
属性的所有元素。
key('idkey', @id)[1]
选择第一个具有article
相同@id
.
因为一个节点不能多次出现在节点集中,如果当前节点与第一个节点相同,则联合. | key('idkey', @id)[1]
将包含一个节点。否则它将包含两个.article
article
@id
检查 的值为count()
one 仅选择第一个具有 any 的元素@id
。
这样做的另一种方法,我更喜欢的方法是generate-id
像这样使用
select="article[generate-id() = generate-id(key('idkey', @id)[1])]"
它通过比较它们生成的 ID 直接检查当前元素是否与集合中的第一个元素相同。