На что ссылается current () внутри предиката, который находится внутри for-each в XSLT 1.0? - PullRequest
1 голос
/ 15 января 2020

Очень часто я вижу код, похожий на этот:

<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() и . имеют немного разные значения в одном конкретном c сценарии. Поэтому мне интересно, будет ли следующее также правильным, позволяя избавиться от почти бесполезной переменной 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, потому что он находится в предикате, или artist от for-each.

Ответы [ 2 ]

2 голосов
/ 15 января 2020

Ну, 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> (но не * 1024) *).

По сути, . - это концепция XPath. Это относится к разным узлам в разных местах в выражении XPath. current() - это концепция XSLT. Он ссылается на один узел, пока не изменится контекст обработки программы XSLT. Он также недоступен за пределами XSLT.

1 голос
/ 15 января 2020

Я предпочитаю объяснять это иначе, чем @Tomalak (хотя его объяснение не является неправильным).

Думайте о current () как о переменной, а не как о функции. Его легко можно было бы назвать $ xsl: current. Где бы вы ни увидели выражение XPath в таблице стилей, скажем select="XXXXXX", затем замените его на

let $xsl:current := . return XXXXXX

Так что, когда выполнение переключается с XSLT на XPath, переменная $xsl:current неявно связана со значением " ". и когда "." изменяется из-за конструкции XPath, такой как предикат, переменная $xsl:current сохраняет свое первоначальное значение.

...