XSLT了解generate-id的工作方式

Sak*_*vel 4 xslt

继续这个链接xslt返回以下兄弟姐妹的选择 我想知道,这里,这个的目的是什么generate-id以及它在这个匹配协议中是如何理解的.

<xsl:for-each select="/items/item[@lcn='005417714']">
  <xsl:for-each select="following-sibling::*[generate-id(preceding-sibling::item[@lcn != ''][1]) = generate-id(current())]">
  </xsl:for-each>
</xsl:for-each>
Run Code Online (Sandbox Code Playgroud)

任何想法,请分享.

Ian*_*rts 13

规范generate-id是它将始终为同一节点返回相同的ID,为不同的节点返回不同的ID.因此,比较generate-id两个节点的值是检查它们是否是同一节点的方式,而不是只有两个恰好具有相同值的节点.

current()为您提供当前的"顶级"上下文节点 - 在谓词之外current()是相同的.,但在谓词表达式内部是.指谓词正在测试的节点,而current()仍然指的是"外部.".

现在在你的例子中

following-sibling::*[generate-id(preceding-sibling::item[@lcn != ''][1])
                      = generate-id(current())]
Run Code Online (Sandbox Code Playgroud)

外部上下文节点是一个item元素(外部for-each当前正在查看的元素).所以从item表达式开始将选择:

following-sibling::*                      --- all the following sibling elements
 [                                        --- such that
  generate-id(                            --- the identity of
   preceding-sibling::item[@lcn != ''][1] --- that element's nearest preceding
                                              item with a non-empty lcn attribute
  )
  =                                       --- is the same as
  generate-id(current())                  --- the identity of the item we started
                                              with
 ]
Run Code Online (Sandbox Code Playgroud)

换句话说,这个<item lcn="005417714">(不包括)和下一个<item lcn="anything-non-empty">(包括)之间的所有兄弟元素.

以相关问题为例:

<item id="00100687" label="A/161i r" lcn="005417714" notes="A/161-182"/>
<item id="00100688" label="A/161i v" lcn="" notes=""/>
<item id="00100819" label="A/182ii v" lcn="" notes=""/>
<item id="00100820" label="A/182iii r" lcn="" notes=""/>
<item id="00100821" label="A/182iii v" lcn="" notes=""/>
<item id="00100822" label="A/183i r" lcn="005417715" notes="A/183-218"/>
<item id="00100823" label="A/183i v" lcn="" notes=""/>
<item id="00100975" label="A/216iii r" lcn="" notes=""/>
Run Code Online (Sandbox Code Playgroud)

如果当前上下文节点是itemwith,id="00100687"则select将提取项目00100688,00100819,00100820,00100821和00100822.如果要排除00100822,则必须添加另一个谓词

following-sibling::*[@lcn = '']
                    [generate-id(preceding-sibling::item[@lcn != ''][1])
                      = generate-id(current())]
Run Code Online (Sandbox Code Playgroud)