как написать узел CDATA с помощью libxml2?

Я использую 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>

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


person Stéphane    schedule 12.04.2011    source источник


Ответы (2)


Догадаться. Хитрость заключается в том, чтобы знать, что текстовое содержимое 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>
person Stéphane    schedule 12.04.2011
comment
Стефан Что за документ во второй строке кода. Это docptr. Есть ли способ обойтись без использования docptr. - person Kranthi Kumar; 10.01.2014
comment
@Stephane xmlNewChild принимает 3 параметра. не 4. - person milaniez; 22.02.2017
comment
@milaniez Обратите внимание, что я написал это в 2011 году. С 2011 по 2017 год многое изменилось! - person Stéphane; 22.02.2017
comment
@Стефан Мой плохой! Он принимает 4 аргумента. - person milaniez; 24.02.2017
comment
@KranthiKumar Как насчет cdataPtr = xmlNewCDataBlock( parentPtr->doc, "Testing 1 < 2", 13 ); ? - person Danny Holstein; 04.01.2021

Я не могу сказать за все версии 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 или нет.

person milaniez    schedule 22.02.2017