Это обычная ошибка, из-за чего стоит «//». Многие люди предполагают, что он обозначает ось потомка, но на самом деле он обозначает /descendant-or-self::node()/
.
//Name[last()]
- это сокращение от /descendant-or-self::node()/Name[last()]
, что делает более очевидным тот факт, что это выражение на самом деле содержит два шага:
/descendant-or-self::node()
, который выбирает узел контекста и всех его потомков, и
Name[last()]
, который выбирает последнего <Name>
дочернего элемента контекстного узла.
Шаг # 2 оценивается один раз для каждого узла, возвращаемого шагом 1. Если шаг 1 возвращает 10 узлов, то шаг 2 (и, следовательно, все выражение) также может возвращать до 10 узлов.
Если вместо этого вы заключите выражение в скобки, вы можете использовать «фильтр выражений», а не «пошаговый фильтр»: (//Name)[last()]
Это гарантирует, что все выражение будет возвращать не более 1 <Name>
элемента, в частности, последний элемент в порядке документа среди всех элементов, возвращаемых выражением слева от него.
Для более подробной информации и нюансов, проверьте эту ветку электронной почты: http://markmail.org/thread/otd3iz5lag72emq4#query:+page:1+mid:qdsrmjrbbdvve3c3+state:results
И эта статья: http://developer.marklogic.com/blog/xpath-punctuation-part-5