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" ]