XPath: Как выбрать элементы на основе их стоимости?
Я новичок в использовании XPath, и это может быть основным вопросом. Пожалуйста, несите меня и помогите мне в решении проблемы. У меня есть XML файл:
<RootNode>
<FirstChild>
<Element attribute1="abc" attribute2="xyz">Data</Element>
<FirstChild>
</RootNode>
Я могу проверить наличие тега <Element>
с помощью:
//Element[@attribute1="abc" and @attribute2="xyz"]
Теперь я также хочу проверить значение тега для строки "Data"
. Для достижения этой цели мне сказали:
//Element[@attribute1="abc" and @attribute2="xyz" and Data]
При использовании более позднего выражения я получаю следующую ошибку:
Сообщение об ошибке утверждения: Нет согласованных узлов //Element[@attribute1="abc" and @attribute2="xyz" and Data]
Просьба предоставить мне ваш совет, действительно ли выражение XPath, которое я использовал, действительно. Если нет, то какое будет действительное выражение XPath?
Ответы
Ответ 1
Условие ниже:
//Element[@attribute1="abc" and @attribute2="xyz" and Data]
проверяет наличие элемента данных в элементе, а не на значение элемента Data.
Вместо этого вы можете использовать
//Element[@attribute1="abc" and @attribute2="xyz" and text()="Data"]
Ответ 2
//Element[@attribute1="abc" and @attribute2="xyz" and .="Data"]
Причина, по которой я добавляю этот ответ, заключается в том, что я хочу объяснить взаимосвязь .
и text()
.
Во-первых, при использовании []
существует только два типа данных:
-
*[number]
выберите node из node -set
-
*[bool]
, чтобы отфильтровать node -set из node -set
В этом случае значение оценивается как boolean по функции boolean()
, и существует правило:
Фильтры всегда оцениваются относительно контекста.
Если вам нужно сравнить text()
или .
со строкой "Data"
, она сначала использует функцию string()
, чтобы преобразовать их в тип строки, чем получает логический результат.
В string()
есть два важных правила:
-
Функция string()
преобразует a node -set в строку, возвращая строковое значение первого node в node -set, что в некоторых случаях может привести к неожиданным результатам.
text()
- относительный путь, возвращающий node -set, содержащий весь текст node текущего node (контекст node), например ["Data"]
.
Когда он оценивается с помощью string(["Data"])
, он вернет первый node из node -set, поэтому вы получите "Данные" только тогда, когда в node -set есть только один текст node.
-
Если вы хотите, чтобы функция string()
конкатенировала весь дочерний текст, вы должны передать один node вместо node -set.
Например, мы получаем node -set ['a', 'b']
, вы можете передать туда родительский node в string(parent)
, это вернет 'ab'
, а причина string(.)
в вашем случае вернет конкатенированная строка "Data"
.
Оба способа получат тот же результат только тогда, когда есть текст node.
Ответ 3
Это:
//Element[@attribute1="abc" and @attribute2="xyz" ]