Чтобы получить второй такой элемент в документе, используйте:
(//x/y[@b])[2]
Предположим, вы хотите пойти другим путем.То есть у вас есть один из этих узлов, и вы хотите знать его общее положение.Как правило, для любого выражения <expr>
верно следующее:
$n = count((<expr>)[$n]/preceding::*[count(.|<expr>)=count(<expr>)])
То есть положение N-го элемента, выбранного с помощью <expr>
, можно найти путем подсчета всех предыдущих элементов, также выбранных этимвыражение.Используя аналогичные методы, мы можем найти положение некоторого узла, который будет выбран более общим выражением, в пределах набора всех узлов, выбранных этим выражением.
Например, предположим, что мыиметь следующий документ:
<x>
<y b="true"/>
<y b="true"/>
<y/>
<y/>
<x><y b="true"/><y/><y b="true">77</y></x>
<y/>
<y/>
</x>
И мы хотим знать позицию в документе узла в /*/*/y[.='77']
среди всех узлов, выбранных //x/y[@b]
.Затем используйте следующее выражение:
count(/*/*/y[.='77']/preceding::*[count(.|//x/y[@b])=count(//x/y[@b])]) + 1
Более конкретное разовое решение выглядит следующим образом:
count(/*/*/y[.='77']/preceding::y[parent::x and @b]) + 1
Результат (в обоих случаях):
4
Примечание: Предполагается, что /*/*/y[.='77']
и (<expr>)[$n]
выше фактически выбирают какой-либо узел в документе.Если нет, результат будет ошибочным 1
из-за добавления 1 к результату подсчета.По этой причине этот метод, вероятно, наиболее полезен при работе с контекстным узлом или когда гарантируется, что ваше начальное выражение выбирает узел.(Конечно, можно также использовать начальную проверку ошибок.)