我经常看到这样的代码:
<xsl:for-each select="/catalog/cd/artist">
<xsl:sort select="artist"/>
...business logic...
<xsl:variable name="artistNum" select="artist_number"/>
<xsl:value-of select="/catalog/cd/song[song_artist_number = $artistNum]/song_title"/>
</xsl:for-each>
变量artistNum
仅在value-of
中使用一次,以确保使用正确的节点。这些数字的作用类似于 SQL 中的外键,但在 XML 中。 我在W3Schools上读到,在一个特定场景中,current()
和.
的含义确实略有不同。所以我想知道以下内容是否也是正确的,允许摆脱几乎无用的变量artistNum
。
<xsl:for-each select="/catalog/cd/artist">
<xsl:sort select="artist"/>
...business logic...
<xsl:value-of select="/catalog/cd/song[song_artist_number = current()/artist_number]/song_title"/>
</xsl:for-each>
但我不确定current()
在这种情况下指的是song
,因为它在谓词中,还是来自for-each
的artist
。
嗯,current()
指的是当前节点。 :)
<xsl:for-each select="/catalog/cd/artist">
<!-- processes `<artist>` elements - current() always refers to that element --->
</xsl:for-each>
current()
的存在是为了克服以下问题:.
引用 XPath 谓词正在操作的节点,并且 XPath(从其有限的世界视图中(无法访问 XSLT 的上下文。
这是没有意义的,因为<artist_number>
可能不是<song>
的孩子:
<xsl:value-of select="/catalog/cd/song[song_artist_number = ./artist_number]/song_title"/>
这是有道理的,因为<artist_number>
可能是<artist>
的孩子:
<xsl:for-each select="/catalog/cd/artist">
<xsl:value-of select="/catalog/cd/song[song_artist_number = current()/artist_number]/song_title"/>
</xsl:for-each>
XSLT 中的一些内容更改了current()
节点 - 最明显的是<xsl:for-each>
和<xsl:apply-templates>
(但不是<xsl:call-template>
(。
从根本上说,.
是一个 XPath 概念。它引用 XPath 表达式中不同位置的不同节点。current()
是一个 XSLT 概念。它引用单个节点,直到 XSLT 程序的处理上下文更改。它在 XSLT 之外也不可用。
我更喜欢用与@Tomalak不同的方式解释它(尽管他的解释没有错(。
将 current(( 视为变量而不是函数。它可以很容易地被命名为$xsl:current。无论您在样式表中看到 XPath 表达式的哪个位置,请说select="XXXXXX"
,然后将其替换为
let $xsl:current := . return XXXXXX
因此,每当执行从 XSLT 切换到 XPath 时,$xsl:current
变量都会隐式绑定到值 ".";当 "." 由于 XPath 构造(如谓词(而更改时,变量$xsl:current
将保留其原始值。