Как написать узел CDATA, используя libxml2? - PullRequest
1 голос
/ 12 апреля 2011

Я использую libxml2 для чтения / записи XML-файлов.Сейчас я пытаюсь написать узел CDATA.

Вот что я попробовал:

nodePtr = xmlNewChild( parentPtr, NULL, "foo", NULL );
xmlNodeSetContentLen( nodePtr, "<![CDATA[\nTesting 1 < 2\n]]>", len );

Однако это приводит к следующему закодированному тексту:

<foo>&lt;![CDATA[
Testing 1 &lt; 2
]]&gt;</foo>

Я думаю, что, возможно, может быть специфичный для CDATA API libxml2.Или, может быть, мне нужно вызвать что-то еще, чтобы сказать libxml2, что он не должен автоматически кодировать содержимое узла?

Ответы [ 2 ]

4 голосов
/ 13 апреля 2011

Разобрался. Хитрость заключается в том, чтобы знать, что текстовое содержимое CDATA на самом деле является дочерним, а не частью текущего узла, и критически важным API для вызова является xmlNewCDataBlock (). Используя тот же пример, что и выше:

nodePtr = xmlNewChild( parentPtr, NULL, "foo", NULL );
cdataPtr = xmlNewCDataBlock( doc, "Testing 1 < 2", 13 );
xmlAddChild( nodePtr, cdataPtr );

Это приведет к следующему xml:

<foo><![CDATA[Testing 1 < 2]]></foo>
0 голосов
/ 22 февраля 2017

Я не могу сказать для всех версий libxml2, но согласно libxml2-2.9.4 часть doc возвращающего узла xmlNewChild происходит от его родителя. Также родительский элемент дочернего узла, возвращаемый из xmlNewCDataBlock, устанавливается параметром doc. Так что хорошей практикой будет следующее:

const char str[] = "said the kitty";
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "meow");
xmlNodePtr cdata_node = xmlNewCDataBlock(node->doc, BAD_CAST str, strlen(str));
xmlAddChild(node, cdata_node);

Полученный xml равен

<meow><![CDATA[said the kitty]]></meow>

И не имеет значения, является ли node частью xmlDoc или нет

...