CDATA внутри обработки PCDATA в XML
Если у нас есть следующий элемент XML:
<x>a < b</x>
и еще один
<y>a<![CDATA[ < ]]>b</y>
Сделайте оба элемента
x
и
y
иметь ценность
a < b
? Второй пример действителен, распространен, рекомендован или что-то в этом роде?
АФАК
y
имеет три дочерних элемента - PCDATA
a
, CDATA
<
и PCDATA
b
и некоторые библиотеки разбирают это именно так. С другой стороны, https://pugixml.org/ возвращается только для одного
a
как ценность для
x
(вспомогательная функция).
1 ответ
Между ними есть принципиальная разница:
CDATA означает символов данных, в то время как PCDATA означает разобранные символьные данные, которые уже дает нам подсказку в правильном направлении, почему парсеры могут вести себя по- разному, в зависимости от уровня их соответствия.
Разделы CDATA - это строгое и чистое избавление от всего, что находится между
<![CDATA[
и
]]>
теги. Ничто из того, что здесь написано, вообще не должно анализироваться процессором XML! Соответствующий синтаксический анализатор XML просто игнорирует что-либо здесь и незаметно передает его любому приложению, которое запросило XML (которое затем может обработать его самостоятельно). Вот почему мы можем разместить здесь любые данные с использованием диких символов, при этом XML не станет недействительным.
<
это Сущность, точнее, Сущность персонажа. Сущности - это "заполнители" или "маркеры", которые заменяются содержанием. Это означает, что объект также PCDATA (Проанализированные символьные данные). Он анализируется парсером XML, который затем интерпретирует его (пытается разрешить его содержимое), чтобы он мог заменить им объект.
Что касается значения данных, нам может потребоваться больше информации о приложении, которое запрашивает XML. В области инструментов обработки XML (XSD, XSLT, XPath, XQuery и т. Д.) Он должен выходить в обоих случаях как любой из типов данных XPath
text()
,
xs:string()
или же
xs:untypedAtomic
, в зависимости от того, какую функцию вы использовали для доступа к нему. Например:
let $t := <xml>Text <![CDATA[test]]> bla.</xml>
return $t/data() instance of xs:untypedAtomic
let $t := <xml>Text <![CDATA[test]]> bla.</xml>
return $t/string() instance of xs:string
let $t := <xml>Text <![CDATA[test]]> bla.</xml>
return $t/text() instance of text()
все в результате
true
.
Однако для любого приложения, которое не работает с моделью данных XML, результатом должен быть просто текст, который находился между тегами элементов.
Здесь есть интересная заметка и целая ветка по этой и смежным темам.