Текущий узел - это то, над чем сейчас работает шаблон. Обычно это также контекстный узел, но контекстный узел имеет особое значение во вложенном выражении XPath (часть в квадратных скобках). Там это относится к любому узлу, который в настоящее время тестируется на соответствие. Следовательно, узел контекста изменяется в выражении XPath, но не в текущем узле.
Узел контекста может быть сокращен точкой (.
) или иногда полностью пропущен. Это, вероятно, немного сбивает с толку, потому что за пределами вложенного выражения точка обозначает текущий узел. (В этом случае текущий узел оказывается узлом контекста, поэтому можно сказать, что он является текущим узлом только приблизительно, и его более правильно называют узлом контекста. Но даже спецификация называет его текущим узлом.) 1004 *
Поскольку точка дает вам узел контекста, во вложенном выражении XPath пользователю нужен способ возврата к текущему узлу, который обрабатывается текущим шаблоном. Вы можете сделать это с помощью функции current()
.
Различение этих двух полезно в некоторых случаях. Например, предположим, у вас есть какой-то XML-код, подобный следующему:
<a>
<b>
<c>foo<footnote fn="1"/></c>
<d>bar</d>
</b>
<b>
<c>baz</c>
<d>aak<footnote fn="2"/></d>
</b>
<b>
<c>eep</c>
<d>blech<footnote fn="2"/></d>
</b>
<footnote-message fn="1">Batteries not included.</footnote>
<footnote-message fn="2">Some assembly required.</footnote>
</a>
Теперь предположим, что вы хотите преобразовать его в LaTeX следующим образом:
foo\footnote{Batteries not included.}
bar
baz
aak\footnote{Some assembly required.}
eep
blech\footnotemark[2]
Хитрость заключается в том, чтобы определить, использовалась ли уже сноска или нет. Если вы впервые столкнулись со сноской, вы хотите написать команду \footnote
; в противном случае вы хотите написать команду \footnotemark
. Вы можете использовать код XSL следующим образом:
<xsl:choose>
<xsl:when test="count(preceding::*[./@fn = current()/@fn]) = 0">\footnote{...}</xsl:when>
<xsl:otherwise>\footnotemark[...]</xsl:otherwise>
</xsl:choose>
Здесь мы сравниваем атрибут * context-node fn
(из результатов набора preceding::*
) с атрибутом current-node fn
. (На самом деле вам не нужно говорить ./@fn
; вы можете просто сказать @fn
.)
Короче говоря, контекстный узел оставляет вас внутри предиката XPath; текущий узел выходит за пределы предиката, обратно к узлу, обрабатываемому текущим шаблоном.