Могу ли я создать значение для отсутствующего тега в XPath?

У меня есть приложение, которое извлекает данные из файла XML с использованием XPath. Если узел в этом исходном XML-файле отсутствует, я хочу вернуть значение "N/A" (очень похоже на функцию Oracle NVL). Хитрость в том, что приложение не поддерживает XSLT; Я хотел бы сделать это, используя только XPath и XPath.

Это возможно?

5 ответов

Решение

Это можно сделать, но только если возвращаемое значение, когда узел существует, является строковым значением узла, а не самого узла. XPath

substring(concat("N/A", /foo/baz), 4 * number(boolean(/foo/baz)))

вернет строковое значение baz элемент, если он существует, в противном случае строка "N/A".

Чтобы обобщить подход:

substring(concat($null-value, $node),
          (string-length($null-value) + 1) * number(boolean($node)))

где $null-value это строка с нулевым значением и $node выражение для выбора узла. Обратите внимание, что если $node оценивает набор узлов, который содержит более одного узла, используется строковое значение первого узла.

Краткий ответ: нет. Такая функция была рассмотрена и явно отклонена для версии 2 спецификации XPath (см. Ненормативный раздел "Иллюстративные пользовательские функции").

Для пустых узлов вам нужно

boolean(string-length($node))

(Вы можете пропустить вызов number() поскольку приведение от логического к числу подразумевается здесь.)

Это можно сделать с помощью XPath 1.0. Скажи у тебя

<foo>
  <bar/>
</foo>

Если вы хотите проверить, если foo имеет baz ребенок,

substring("N/A", 4 * number(boolean(/foo/baz)))

вернет "N/A", если выражение /foo/baz возвращает пустой набор узлов, в противном случае он возвращает пустую строку.

@jelovirt

Так что, если я правильно понимаю, мы объединяем ответ по умолчанию и значение узла, а затем принимаем правильное подмножество результирующей строки, проверяя наличие узла, чтобы установить смещение равным нулю или положению сразу после моего строка по умолчанию. Это самый извращенный поворот языка, который я когда-либо видел. (Я люблю это!)

Чтобы пояснить, что вы сказали, этот подход работает, когда узел отсутствует, а не когда узел пуст. Но, заменив "number(boolean($node))" на "string-length($node)", он будет работать на пустых узлах.

Другие вопросы по тегам