如何理解 xslt 语法 [not(.=preceding::*)]

Dav*_*Dai 0 xml xslt

我正在查看我的同事创建的 XSLT 文件,它包含以下代码片段:

<xsl:for-each select="/vpf:Msg/vpf:Body/vpf:Payload[./@id=&apos;atom6&apos;]/row/DocEntry[not(.=preceding::*)]">
                <DocEntry>
                    <xsl:value-of select="."></xsl:value-of>
                </DocEntry>
</xsl:for-each>
Run Code Online (Sandbox Code Playgroud)

[not(.=preceding::*]
在阅读了一些关于锚点的用法之后,我很难理解这部分preceding,在我看来,这部分根本没有做任何事情。有人可以帮助我了解我的同事可能想在这里做什么吗?

Mic*_*Kay 5

. = preceding::*
Run Code Online (Sandbox Code Playgroud)

如果当前节点的值等于某个先前节点的值,则为 true。这里您需要理解四个概念,我不确定您对其中哪一个感到困难:

  • .表示当前节点。您绝对需要理解这个概念才能理解 XPath

  • =在 XPath 中有点不寻常:它测试左侧的任何项目是否等于右侧的任何项目,实际上X = Y意味着“X 中的某些项目等于 Y 中的某些项目”。

  • preceding::*按文档顺序选择同一文档中当前元素之前的所有元素。实际上,给定两个元素 A 和 B,如果 A 的结束标记在文档中出现得早于 B 的开始标记,则 A 位于 B 之前。

  • 字符串值:给定像“=”这样应用于节点的操作,它实际上对节点的字符串值进行操作。对于像 之类的简单元素<x>23</x>,该元素的字符串值为 23。

所以

not(. = preceding::*)
Run Code Online (Sandbox Code Playgroud)

测试该元素是否与之​​前的所有元素不同

//*[not(. = preceding::*)]
Run Code Online (Sandbox Code Playgroud)

因此选择所有不重复的元素。

与 XSLT 1.0 中的大多数棘手问题一样,使用 XSLT 2.0 当然这会变得容易得多 - 即使您不幸被 XSLT 1.0 困住,也有更好的方法使用键来解决分组问题。