Могу ли я создать значение для отсутствующего тега в XPath?
Вопрос
У меня есть приложение, которое извлекает данные из XML-файла, используя XPath.Если узел в этом исходном файле XML отсутствует, я хочу вернуть значение "N / A" (очень похоже на функцию Oracle NVL).Хитрость в том, что приложение не поддерживает XSLT;Я бы хотел сделать это, используя XPath и только XPath.
Возможно ли это?
Решение
Это можно сделать, но только если возвращаемое значение, когда узел существует, является строковым значением узла, а не самим узлом . 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
оценивается как набор узлов, который содержит более одного узла, используется строковое значение узла first .
Другие советы
Краткий ответ: нет. Такая функция была рассмотрена и явно отклонена для версии 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)", вместо этого он будет работать с пустыми узлами.