c++ - 使用 boost::property_tree 编写 CDATA XML 节点
问题描述
我正在尝试使用 boost::property_tree 编写一个包含 CDATA 节点的 XML 文件。但是,由于诸如<
, >
,&
等字符在编写 XML 文件时会自动转义,例如
xml.put("node", "<![CDATA[message]]>")
将显示为
<node><![CDATA[message]]></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(), ">", ">");
cleaned_xml = boost::replace_all_copy(cleaned_xml, "<", "<");
cleaned_xml = boost::replace_all_copy(cleaned_xml, "&", "&"); // last one
std::ofstream fo(path);
fo << cleaned_xml;
更详细的解决方案应包括找到开头<![CDATA[
和结尾]]>
,并仅在这些限制内替换以避免替换正确转义的符号。
这个答案中提出了另一种解决方案,但我从未使用过它。