【问题标题】:XSLT - Key() functionXSLT - Key() 函数
【发布时间】:2013-05-25 16:33:26
【问题描述】:

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

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

有没有人可以简要解释一下这个 for-each 循环中发生了什么?

关键是:&lt;xsl:key name="idkey" match="/newspapers/newspaper" use="@id"/&gt;

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

谢谢。

【问题讨论】:

    标签: xslt key iteration


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      在这个for-each元素中

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

      for-each 被应用于每个@id 属性的第一个 article 元素。

      • 调用key('idkey', @id) 正在选择与当前元素具有相同@id 属性的所有article 元素。

      • key('idkey', @id)[1] 选择具有相同@id 的所有article 元素中的第一个

      • 因为一个节点不能多次出现在一个节点集中,如果当前article是同一个节点,联合. | key('idkey', @id)[1]将包含一个节点首先 article 与相同的@id。否则它将包含两个

      • 检查 count() 的值为 one 只选择第一个具有任何 @id 的元素。

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

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

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

      【讨论】:

      • 抱歉,您在这里错了,因为键 idkey 不是文章/@id 的键,而是报纸/@id。还是我错过了什么?
      • @hr_117:在写这篇文章时,我希望 OP 已经显示了 idkey 的声明。不知怎的,我忽略了它。但事实上,select XPath 非常奇怪,因为key() 返回的任何节点集都不能包含article 元素,谓词与1 + count(key('idkey', @id)[1]) = 1 相同,或者如您所说,not(key('idkey', @id)) .这显然是一个错误。
      猜你喜欢
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多