В каталоге есть несколько XML-файлов, как это:XPath: Что соответствует оператору «/» в начале корневого пути?
File # 1: <root myAtt="one"/>
Файл № 2: <root myAtt="two"/>
Я хочу, чтобы выбрать первый документ. Для этого я использую следующий запрос (предполагается, что каталог называется «MyDocs»):
collection('myDocs')[/root/@myAtt = 'one']
(я знаю, что я мог бы использовать doc()
, чтобы выбрать документ, представляющий интерес Но этот пример является лишь упрощенным. версию реальной ситуации, с которой я столкнулся, в которой мне приходится работать с коллекцией, извлеченной из базы данных.)
Если я запустил этот запрос на Saxon-HE 9.6, я получаю то, что ожидаю: <root myAtt="one"/>
. Но если я запустил тот же запрос на BaseX 8.3, я неожиданно получаю: <root myAtt="one"/><root myAtt="two"/>
. Возникает путаница.
По-видимому, ведущее /
выражения пути внутри предиката (выражение «корневого пути» в соответствии с доктором Кей в XSLT 2.0 и XPath 2.0 4th Edition) обрабатывается по-разному в рамках реализации.
В этом случае /
должен выбрать узел документа дерева, содержащий узел контекста. И это то, что делает Саксон.
Но в BaseX /
, похоже, выбирает последовательность узлов документа, фильтруемых предикатом. Это объясняет (если я правильно понимаю), что предикат оценивает значение true для всех документов, учитывая особое поведение оператора общего сравнения =
(всегда есть как минимум один элемент в последовательности результатов, равный «одному»)).
Итак, поведение оператора /
в зависимостях корневых путей зависит от реализации?
В этом случае, я получаю единый документ в обеих реализациях. Это то же самое, что если я использую 'collection ('myDocs') [./ root/@ myAtt = 'one']': один единственный документ. Отсюда мой вопрос о корневых выражениях пути. Это единственный случай, когда поведение реализаций расходится. – ARX
Ваше замешательство, вероятно, связано с тем, что вы, кажется, думаете, что корневой узел и элемент документа - одно и то же. Они не. Элемент document является дочерним элементом корневого узла (что особенно важно, поскольку он может содержать не более одного дочернего элемента). – Tomalak
@Tomalak: кристально ясно, что узел документа и корневой элемент - это разные вещи. Это единственный способ, которым предикат '[/ root/@ myAtt = 'one']' мог работать так же, как и в Саксоне.Ведущий '/' соответствует узлу _document_ дерева, содержащего узел контекста (который сам является узлом документа - это тип узлов, возвращаемых методом collection(), в этом случае -); в то время как первый шаг оси «root» совпадает с его единственным дочерним элементом: _root element_. Именно поэтому при отбрасывании ведущего '/' обе реализации могут выводить один и тот же результат: один документ. – ARX