Ссылка на позицию текущего узла в выражении xpath
(Примечание: эта запись была отредактирована, чтобы показать конкретный случай использования. Смотрите снизу.)
Я хочу использовать текущее значение узла position () внутри выражения xpath (в котором изменяется контекст). К сожалению, я не вижу никакого простого способа сделать это, потому что current()/position() всегда кажется равным 1.
[я предполагаю, что это потому, что current()/position() говорит: "Какова позиция узла current () в контексте... одноузловый набор, содержащий только текущий().]
Чтобы быть точным, предположим, что у меня есть последовательность узлов $seq, и я хочу вернуть*n * - й узел в последовательности ($seq[n]), где n равно текущему значению position () (то есть значению position () до вычисления оператора).
Очевидно, что $seq[position()] не будет работать, потому что это расширяется до seq[position () = position ()], возвращая всю последовательность.
$seq[position (current ())] - это болтовня.
Единственное, что я смог найти, это кажется, может быть, работа-это
for $pos in position() return $seq[$pos]
Я предполагаю, что есть более простой способ.
Edit Мне было предложено привести более конкретный пример того, что я пытаюсь сделать. Я действительно нашел ответ первого лица достаточным для моих потребностей, хотя и не намного проще, чем то, что я придумал сам (вариант "for $pos in position() return $correctOrder[$pos]").
Вот реальная ситуация: у меня есть набор "сеансовых" узлов, каждый из которых имеет атрибут @startTime. Я нужно найти, какие из них не упорядочены по отношению к этому атрибуту @startTime, или, по крайней мере, не в том месте, где они были бы, если бы узлы входного документа были правильно отсортированы по @startTime.
Это всего лишь один из многих тестов, которые выполняются на каждом из узлов сеанса.
Что я хотел сделать, так это создать последовательность с узлами в правильном порядке и сравнить N-й элемент в упорядоченной последовательности документов с N-м элементом в правильно упорядоченной последовательности. последовательность.
Что-то вроде этого:
<xsl:template match="/">
<xsl:variable name="correctOrder" as="node()*">
<xsl:for-each select="session">
<xsl:sort select="@xs:dateTime(@startTime)"/>
<xsl:sequence select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="session">
<xsl:if test="current()/@startTime eq
$correctOrder[<-here I want to put the value "position()" had prior to this <xsl:if> statement->]/@startTime"
<error description="Node out of order."/>
</xsl:if>
</xsl:for-each>
2 ответа:
Ну, поскольку вы отметили свой вопрос как XSLT 2.0, я бы использовал переменную, например
<xsl:variable name="pos" as="xs:integer" select="position()"/>
И затем использовать эту переменную, например
<xsl:sequence select="$seq[$pos]"/>
Примечание : я прошу прощения, что из-за ошибки в форматировании кода SO этот код не имеет отступов.
Вот пример, иллюстрирующий общую схему, использующую ту же позицию :
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:variable name="vSeq1" select="/*/names/*/text()"/> <xsl:variable name="vSeq2" select="/*/values/*/text()"/> <xsl:template match="/"> <xsl:sequence select= "for $i in 1 to count($vSeq1) return ($vSeq1[$i], '=', $vSeq2[$i], '
') "/> </xsl:template> </xsl:stylesheet>
Когда это преобразование применяется к следующему XML-документу :
<t> <names> <name>N1</name> <name>N2</name> <name>N3</name> <name>N4</name> <name>N5</name> </names> <values> <value>V1</value> <value>V2</value> <value>V3</value> <value>V4</value> <value>V5</value> </values> </t>
Желаемый, правильный результат получается :
N1=V1 N2=V2 N3=V3 N4=V4 N5=V5