Синтаксис XPath, с или без суффикса "/ text ()"

xml xpath xpath-2.0 domxpath xpath-1.0

26 просмотра

2 ответа

На разных сайтах синтаксис XPath отличается, в первую очередь необходим суффикс "/ text ()" .

Цитирование синтаксиса без суффикса:

Цитирование синтаксиса с необходимостью суффикса:

Насколько мне известно, разные библиотеки также работают только с суффиксом или без него (раньше я не сталкивался с таковым, как с суффиксом, так и без него).

Не требует суффикса:

Требуется суффикс:

  • Java JRE родная реализация XPath

Казалось бы, скорее всего, есть разница между реализацией библиотеки XPath, предназначенной для использования с XML, и для использования с DOM? Если так, в чем разница и где я могу найти разницу?

Автор: Jasper Teng Источник Размещён: 16.08.2019 12:20

Ответы (2)


3 плюса

Я думаю, что вы ошиблись в диагностике ситуации, и причина ошибочного диагноза (чтобы провести слишком большую аналогию) заключается в том, что вы смотрели на симптомы около 7 пациентов, а не ходили в медицинскую школу и изучали анатомию.

«Анатомия» здесь - это модель данных XDM, которая лежит в основе семантики XPath. Обратите внимание, в частности, что

(а) когда у вас есть такая структура

<title>Water</title>

есть узел элемента, строковое значение которого равно «Вода», и который является родителем отдельного текстового узла, строковое значение которого также равно «Вода».

(б) когда у вас есть такая структура

<title>H<sub>2</sub>O</title>

есть узел элемента со строковым значением «H2O», который является родителем трех дочерних элементов: текстовый узел со строковым значением «H», узел элемента со строковым значением «2» (который сам является родителем другого текста узел ...) и второй текстовый узел со строковым значением "O".

В случае (а) почти все операции дают один и тот же результат, независимо от того, применяется ли он к узлу элемента или к текстовому узлу. Например, contains($x, "ate")будет истинно, $xявляется ли элемент узлом или текстовым узлом. Таким образом, добавление /text()к пути, как правило, является излишним: оно не причиняет вреда, но в этом нет необходимости. Мы часто советуем не делать этого, потому что это делает ваш код более хрупким, если впоследствии структура данных изменяется, не говоря уже о добавлении ненужной детализации.

В случае (b) добавление /text()к вашему пути заставляет вас выбирать два текстовых узла "H" и "O" вместо выбора узла элемента. В XPath 1.0 многие операции (например, contains()) применительно к последовательности из двух текстовых узлов игнорируют все, кроме первого, поэтому contains(x/y/title/text(), "O")возвращают false; в XPath 2.0 будет выдано сообщение об ошибке, говорящее о том, что аргумент метода contains () должен быть одиночным. Если вы просто хотите узнать, содержит ли заголовок букву «O», то гораздо лучше опустить /text()и применить операцию к строковому значению элемента, которое является объединением всех текстовых узлов.

Единственный раз, когда вам нужно использовать «/ text ()», это если вы хотите более глубоко исследовать внутреннюю структуру titleэлемента.

Конечно, возможно, что между реализациями XPath есть различия - не все они на 100% соответствуют стандарту. Но основные реализации довольно совместимы, и если вы найдете разницу, пожалуйста, сообщите нам об этом: будьте явными об исходном документе, выражении пути и различных результатах, полученных в разных реализациях.

Автор: Michael Kay Размещён: 15.08.2019 08:14

0 плюса

Если вы посмотрите на соответствующие спецификации, то обнаружите, что как XPath 1.0 https://www.w3.org/TR/xpath-10/#node-tests, так и спецификацию XPath 2.0 https: //www.w3 .org / TR / xpath20 / # node-tests определяют то, что вы называете «суффиксом» как «тест узла», text()используемый для выбора любого «текстового узла».

Ни одна из спецификаций не использует text()требование, но, конечно, это вариант, который язык имеет и должен выбирать для текстовых узлов, например, со смешанным содержанием элементов и текста и / или комментариев, когда у вас есть причина только для выбора текста узел детей.

Что касается реализаций, я не думаю, что реализация Java XPath 1.0 требует от вас его использовать, единственная причина, по которой некоторые более старые специфичные для DOM коды используют foo/text()вместо простого fooсчитывания строкового содержимого внутри элемента eg, <foo>some example</foo>это то, что в более старых реализациях DOM Если вы выберете Elementузел, у вас не будет свойства или метода для доступа к текстовому содержимому элемента в виде строки, поэтому люди использовали foo/text()для выбора Textдочернего узла Elementи могли затем использовать nodeValueсвойство (Javascript) или getNodeValue()метод (Java). чтобы получить строку с some example. Однако в течение многих лет DOM предоставлял свойство textContentдля Elementузлов, поэтому в наши дни вы можете использовать его fooкак XPath, получить Elementузел и считатьtextContentили getTextContent()соответственно иметь строку some example.

MSXML DOM и XPath также довольно стары и никогда не обновлялись до спецификации W3C DOM Level 3, но у Microsoft с самого начала было свое собственное .textсвойство на узлах элементов, которое вы можете использовать вместо стандартизированных textContent. Тем не менее, в этом контексте я видел похожие попытки явного считывания foo/text()в виде списка узлов, в котором вы можете получить доступ к nodeValueкаждому текстовому узлу в виде строки.

Единственное специфическое для реализации «предпочтение» для использования foo/text()вместо того, что fooя видел, находится в библиотеке lxml Python, если вы хотите напрямую отобразить выбор XPath на список строк Python, в этом случае выражение, подобное foo/text()в контексте eg <data><foo>a</foo><foo>b</foo></data>, даст вам на стороне Python список из двух строк Python с aи bво время использования fooдаст вам список с двумя узлами элемента. Таким образом, в зависимости от ваших потребностей на стороне основного языка, в этом случае его будет проще использовать, foo/text()но вы должны знать, что ввод, подобный <data><foo>a<!-- comment -->b</foo><foo>c</foo></data>, даст вам список с тремя строками.

Автор: Martin Honnen Размещён: 15.08.2019 09:18
Вопросы из категории :
32x32