2011-04-12 60 views
1

我正在使用libxml2读取/写入xml文件。现在我试图写一个CDATA节点。如何使用libxml2编写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-libxml2的API。或者,也许我必须调用别的东西来告诉libxml2不要自动编码节点内容?

回答

3

想通了。诀窍是知道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

斯特凡的一部分,什么都在doc它不会有问题代码的第二行。它是一个docptr。有没有办法做到不使用docptr。 – 2014-01-10 06:37:26

+0

@Stephane xmlNewChild需要3个参数。不是4. – milaniez 2017-02-22 00:52:10

+0

@milaniez请注意,我在2011年写了这篇文章。很多事情在2011年和2017年之间都发生了变化! – 2017-02-22 01:56:19

0

我不能说的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> 

如果nodexmlDoc与否