Могу ли я создать значение для отсутствующего тега в 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)", он будет работать на пустых узлах.