使用 boost::property_tree 写入 CDATA XML-节点
Write CDATA XML-node with boost::property_tree
我正在尝试使用 boost::property_tree 编写包含 CDATA 节点的 XML 文件。然而,由于 <
、>
、&
等字符在写入 XML 文件时会自动转义,例如
xml.put("node", "<![CDATA[message]]>")
将显示为
<node><![CDATA[message]]></node>
在 XML 文件中。有什么方法可以使用 property_tree 正确编写 CDATA 节点,或者这仅仅是库的限制?
Boost documentation 明确表示无法区分 CDATA 和非 CDATA 值:
The XML storage encoding does not round-trip perfectly. A read-write cycle loses trimmed whitespace, low-level formatting information, and the distinction between normal data and CDATA nodes. 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.
少数几次我遇到同样的问题都是针对非常具体的情况,在这些情况下我知道不需要其他转义数据,因此对生成的文件进行简单的 post 处理以替换转义字符够了。
作为一般示例:
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[
和结束 ]]>
,并仅在这些限制内替换以避免替换正确转义的符号。
this answer 中提供了另一种解决方案,但我从未使用过它。
我正在尝试使用 boost::property_tree 编写包含 CDATA 节点的 XML 文件。然而,由于 <
、>
、&
等字符在写入 XML 文件时会自动转义,例如
xml.put("node", "<![CDATA[message]]>")
将显示为
<node><![CDATA[message]]></node>
在 XML 文件中。有什么方法可以使用 property_tree 正确编写 CDATA 节点,或者这仅仅是库的限制?
Boost documentation 明确表示无法区分 CDATA 和非 CDATA 值:
The XML storage encoding does not round-trip perfectly. A read-write cycle loses trimmed whitespace, low-level formatting information, and the distinction between normal data and CDATA nodes. 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.
少数几次我遇到同样的问题都是针对非常具体的情况,在这些情况下我知道不需要其他转义数据,因此对生成的文件进行简单的 post 处理以替换转义字符够了。
作为一般示例:
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[
和结束 ]]>
,并仅在这些限制内替换以避免替换正确转义的符号。
this answer 中提供了另一种解决方案,但我从未使用过它。