使用boost::property_tree编写CDATA XML节点

Write CDATA XML-node with boost::property_tree

本文关键字:CDATA XML 编写 节点 boost property 使用 tree      更新时间:2023-10-16

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

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

将显示为

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

在XML文件中。是否有任何方法可以使用property_tree正确写入CDATA节点,或者这只是库的限制?

Boost文档明确指出,它无法区分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,并仅在这些限制范围内进行替换,以避免替换正确转义的符号。

这个答案中提供了另一个解决方案,但我从未使用过