You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Boost::property_tree::xml_writer_settings避免生成自闭合空标签?

解决Boost.PropertyTree XML Writer生成自闭合空标签的问题

嘿,这个坑我之前踩过!Boost.PropertyTree的XML writer默认会把没有子节点且值为空的元素转换成自闭合标签(比如<a/>),但确实可以通过自定义xml_writer来强制让它输出<a></a>这种展开式的空标签,不需要修改核心库代码。

核心思路:自定义XML Writer

Boost.PropertyTree允许我们传入自定义的writer对象来控制XML的输出格式。我们只需要继承boost::property_tree::xml_writer,重写write_element方法,针对空元素的情况做特殊处理即可。

完整代码示例

#include <boost/property_tree/xml_parser.hpp>
#include <fstream>

using namespace boost::property_tree;

// 自定义XML Writer,强制展开空标签
struct expanded_empty_tag_writer : xml_writer<std::string> {
    // 构造函数,传入缩进字符(默认两个空格)
    expanded_empty_tag_writer(const std::string& indent = "  ") 
        : xml_writer<std::string>(indent) {}

    // 重写元素写入逻辑
    void write_element(const std::string& name, const std::string& value, 
                       const ptree& pt, std::basic_ostream<std::string::value_type>& stream) const override {
        // 判断是否是完全空的元素:没有子节点(包括属性)且值为空
        if (pt.empty() && value.empty()) {
            // 输出展开式的空标签
            stream << indent() << "<" << name << "></" << name << ">" << newline();
        } else {
            // 非空元素使用默认逻辑处理
            xml_writer<std::string>::write_element(name, value, pt, stream);
        }
    }
};

int main() {
    // 读取原XML文件
    ptree tree;
    read_xml("original.xml", tree);

    // 使用自定义writer写入新XML文件
    std::ofstream output_file("output.xml");
    write_xml(output_file, tree, expanded_empty_tag_writer("  "));

    return 0;
}

代码说明

  • 我们的自定义writer会检查元素是否满足「没有子节点(包括属性,因为Boost把属性存在<xmlattr>子节点里)且值为空」的条件,满足的话就输出<tag></tag>格式。
  • 对于带有属性的元素(比如<a id="foo"></a>),因为pt包含<xmlattr>子节点,所以不会触发这个特殊逻辑,会按默认方式输出(当然默认也不会把带属性的元素写成自闭合标签,这点不用担心)。
  • 缩进字符可以通过构造函数自定义,比如用"\t"表示制表符缩进。

注意事项

这个方法适用于所有Boost版本,因为它是基于官方提供的扩展接口实现的,不会依赖版本特定的隐藏参数。如果你的场景里需要保留原XML的空标签格式,这个方案应该能完美解决你的问题。

内容的提问来源于stack exchange,提问作者tsch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:09:15