用boost :: property_tree编写CDATA XML节点

时间:2019-01-04 12:29:03

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

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

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

将显示为

<node>&lt![CDATA[message]]&gt</node> 
XML文件中的

。有没有什么方法可以使用property_tree正确编写CDATA节点,或者这仅仅是库的限制?

1 个答案:

答案 0 :(得分: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;

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

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