【问题标题】:Write CDATA XML-node with boost::property_tree使用 boost::property_tree 编写 CDATA XML 节点
【发布时间】:2023-03-21 17:01:01
【问题描述】:

我正在尝试使用 boost::property_tree 编写一个包含 CDATA 节点的 XML 文件。但是,由于<>& 等字符在写入 XML 文件时会自动转义,类似于

xml.put("node", "<![CDATA[message]]>")

将显示为

<node>&lt![CDATA[message]]&gt</node> 

在 XML 文件中。有没有办法使用 property_tree 正确编写 CDATA 节点,或者这仅仅是库的限制?

【问题讨论】:

    标签: c++ xml boost cdata boost-propertytree


    【解决方案1】:

    Boost documentation 明确表示无法区分 CDATA 和非 CDATA 值:

    XML 存储编码不能完美地往返。读写周期会丢失修剪后的空白、低级格式化信息以及普通数据和 CDATA 节点之间的区别。评论仅在启用时保留。一个写-读周期丢失了修整的空白;也就是说,如果源树的字符串数据以空格开头或结尾,则该空格将丢失。

    在我知道不需要其他转义数据的非常特殊的情况下,我遇到过几次相同的问题,因此对生成的文件进行简单的后处理替换转义字符就足够了。

    作为一般示例:

    std::ostringstream ss;
    pt::write_xml(ss, xml, pt::xml_writer_make_settings<std::string>('\t', 1));
    
    auto cleaned_xml = boost::replace_all_copy(ss.str(), "&gt;", ">");
    cleaned_xml = boost::replace_all_copy(cleaned_xml, "&lt;", "<");
    cleaned_xml = boost::replace_all_copy(cleaned_xml, "&amp;", "&"); // last one
    
    std::ofstream fo(path);
    fo << cleaned_xml;
    

    更详细的解决方案应该包括找到开头&amp;lt;![CDATA[ 和关闭]]&amp;gt,并仅在这些限制内替换以避免替换正确转义的符号。

    this answer 中提出了另一种解决方案,但我从未使用过。

    【讨论】:

    • 在我的情况下,我必须删除 & 号替换,但否则这对我很有用,谢谢!
    猜你喜欢
    • 2018-01-04
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 2013-03-03
    • 1970-01-01
    相关资源
    最近更新 更多