XSLT - Key()函数

时间:2013-05-24 15:20:43

标签: xslt key iteration

我对这个关键功能感到有点困惑:

 <xsl:for-each select="article[count(. | key('idkey', @id)[1]) = 1]>

有没有人可以简单解释这个for-each循环中发生的事情?

关键是:<xsl:key name="idkey" match="/newspapers/newspaper" use="@id"/>

@id是报纸上的一个属性。

感谢。

2 个答案:

答案 0 :(得分:2)

表达式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。但也许它们在某种程度上是相关的。

答案 1 :(得分:-1)

在此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()的值是否为1,只选择第一个包含@id的元素。

这样做的另一种方法,也就是我喜欢的方法,就是像这样使用generate-id

select="article[generate-id() = generate-id(key('idkey', @id)[1])]"

通过比较生成的ID,直接检查当前元素是否与集合中的第一个元素相同。