简体   繁体   English

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

[英]Write CDATA XML-node with boost::property_tree

I'm trying to write an XML-file containing CDATA-nodes using boost::property_tree.我正在尝试使用 boost::property_tree 编写一个包含 CDATA 节点的 XML 文件。 However since characters such as < , > , & , etc. are escaped automatically when writing the XML-file, something like但是,由于在编写 XML 文件时会自动转义诸如<>&等字符,例如

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

will appear as将显示为

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

in the XML-file.在 XML 文件中。 Is there any way to properly write CDATA-nodes using property_tree or is this simply a limitation of the library?有什么方法可以使用 property_tree 正确编写 CDATA 节点,或者这仅仅是库的限制吗?

Boost documentation clearly says that it is not able to distinguish between CDATA and non-CDATA values: Boost 文档明确指出它无法区分 CDATA 和非 CDATA 值:

The XML storage encoding does not round-trip perfectly. XML 存储编码不能完美地往返。 A read-write cycle loses trimmed whitespace, low-level formatting information, and the distinction between normal data and CDATA nodes.读写循环会丢失修剪过的空白、低级格式化信息以及普通数据和 CDATA 节点之间的区别。 Comments are only preserved when enabled.注释仅在启用时保留。 A write-read cycle loses trimmed whitespace;写-读循环丢失修剪的空白; that is, if the origin tree has string data that starts or ends with whitespace, that whitespace is lost.也就是说,如果原始树具有以空格开头或结尾的字符串数据,则该空格将丢失。

The few times I've faced the same problem have been for very specific cases where I knew no other escaped data would be needed, so a simple post-processing of the generated file replacing the escaped characters was enough.我几次遇到同样的问题是在非常特殊的情况下,我知道不需要其他转义数据,因此对生成的文件进行简单的后处理替换转义字符就足够了。

As a general example:作为一般示例:

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;

A more elaborated solution should include finding the opening &lt;![CDATA[ and closing ]]&gt , and replace only within those limits to avoid replacing correctly escaped symbols.更详细的解决方案应该包括找到开头&lt;![CDATA[和结束]]&gt ,并仅在这些限制内进行替换以避免替换正确转义的符号。

Another solution is presented in this answer but I've never used it.此答案中提供了另一种解决方案,但我从未使用过它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM