【问题标题】:how to write a CDATA node using libxml2?如何使用 libxml2 编写 CDATA 节点?
【发布时间】:2011-04-12 09:10:23
【问题描述】:

我正在使用 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 特定的 libxml2 API。或者也许我必须调用其他东西来告诉 libxml2 不要自动编码节点内容?

【问题讨论】:

    标签: libxml2 cdata


    【解决方案1】:

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

    【讨论】:

    • Stéphane 代码第二行的文档是什么。它是一个docptr吗?有没有办法不用docptr。
    • @Stephane xmlNewChild 采用 3 个参数。不是 4.
    • @milaniez 请注意,我在 2011 年写了这篇文章。2011 年到 2017 年之间发生了很多变化!
    • @Stéphane 我的错!它确实需要 4 个参数。
    • @KranthiKumar cdataPtr = xmlNewCDataBlock( parentPtr-&gt;doc, "Testing 1 &lt; 2", 13 ); 怎么样?
    【解决方案2】:

    我不能说所有版本的 libxml2,但是根据 libxml2-2.9.4,xmlNewChild 的返回节点的 doc 部分来自其父节点。同样,从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 并不重要

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 1970-01-01
      • 2011-09-09
      • 1970-01-01
      • 2011-12-25
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多