我正在使用Boost C ++属性树库(https://www.boost.org/doc/libs/1_70_0/doc/html/property_tree.html)来读取和序列化一些简单的XML。
首先,我从XML文档构建属性树-效果很好。
但是,我无法获得对子节点的引用(在下面的示例中为“ b1”),然后序列化其根为“ b1”(包括“ b1”)的整个子树,如下所示:一个新的XML文档。
我尝试使用get_child,但这只会序列化我的子树的根节点的子节点(也许会根据其名称而被期望)。
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
namespace pt = boost::property_tree;
void test() {
pt::ptree tree;
// populate tree
tree.put("a.b1", "value1");
tree.put("a.b2", "value2");
tree.put("a.b1.c1", "");
tree.put("a.b1.c2", "");
tree.put("a.b1.c3", "");
tree.put("a.b1.c4", "");
std::ostringstream os;
pt::write_xml(os, tree);
// 1. dump tree as xml to cout
std::cout << os.str() << std::endl;
/*
here I would like to use some sort of get_subtree
function get a subtree of "tree" starting at and including
node "a.b1", and serialize it as XML:
pt::tree subtree = tree.get_subtree( "a.b1" );
std::ostringstream os1;
pt::write_xml(os1, subtree)
// 2. dump subtree as xml to cout
std::cout << os1.str() << std::endl;
*/
}
我得到1的结果是(我的格式是write_xml放在一行上)
<?xml version="1.0" encoding="utf-8"?>
<a>
<b1>value1
<c1/>
<c2/>
<c3/>
<c4/>
</b1>
<b2>value2
</b2>
</a>
我想在2处得到以下xml,其中“ b1”是新子树的根
<?xml version="1.0" encoding="utf-8"?>
<b1>value1
<c1/>
<c2/>
<c3/>
<c4/>
</b1>
这就是我调用get_child(“ a.b1”)以从“ b1”开始的新子树得到的结果(这次是原始格式):
<?xml version="1.0" encoding="utf-8"?>
b1_value<c1/><c2/><c3/><c4/>
它甚至不是格式正确的XML。
更新 仅出于测试目的,我在原始树的根级别添加了几个元素。这是新代码:
void test() {
pt::ptree tree;
// populate tree
tree.put("a.b1", "b1_value");
tree.put("a.b2", "b2_value");
tree.put("a.b1.c1", "");
tree.put("a.b1.c2", "");
tree.put("a.b1.c3", "");
tree.put("a.b1.c4", "");
tree.put("x", "");
tree.put("x.m", "");
tree.put("y", "");
std::ostringstream os;
pt::write_xml(os, tree);
// dump tree as xml to cout
std::cout << os.str() << std::endl;;
}
并输出:
<?xml version="1.0" encoding="utf-8"?>
<a>
<b1>b1_value
<c1/>
<c2/>
<c3/>
<c4/>
</b1>
<b2>b2_value</b2>
</a>
<x>
<m/>
</x>
<y/>
这显然不是格式正确的XML,也不能直接帮助我,但是它表明该库在处理任何级别的树时都是一致的。
更新 我修改了标题以正确反映我实际上要执行的操作-我不仅在尝试获取子树,而且还将其序列化为XML。我遇到的问题是,仅使用记录的类方法,虽然我可以获得子树,但是序列化遍历了根节点,其子节点(这是我想要的)但遍历了其对等节点(这是不希望的)。 / p>
答案 0 :(得分:0)
该库仅在映射到不同序列化后端的方式上具有吸引力。 (非常简洁)文档中明确指出了这些限制。
虽然令人惊讶。
简化样品:
pt::ptree tree;
// populate tree
tree.put("a.b1", "value1");
tree.put("a.b2", "value2");
tree.put("a.b1.c1", "");
tree.put("a.b1.c2", "");
tree.put("a.b1.c3", "");
tree.put("a.b1.c4", "");
auto options = pt::xml_writer_make_settings<std::string>(' ', 4);
write_xml(std::cout, tree, options);
打印
<?xml version="1.0" encoding="utf-8"?>
<a>
<b1>
value1
<c1/>
<c2/>
<c3/>
<c4/>
</b1>
<b2>value2</b2>
</a>
这部分很简单:
pt::ptree const& subtree = tree.get_child("a.b1");
要使其“正确打印”,请添加一个备考顶级节点:
// option 1
{
pt::ptree fake_root;
fake_root.add_child("b1", subtree);
write_xml(std::cout, fake_root, options);
}
打印
<?xml version="1.0" encoding="utf-8"?>
<b1>
value1
<c1/>
<c2/>
<c3/>
<c4/>
</b1>
如果您认为这很烦人/浪费,您可以可以使用未记录的内部函数来编写单个元素:
// option 2
{
pt::xml_parser::write_xml_element(std::cout, "b1", subtree, 0, options);
}
打印
<b1>
value1
<c1/>
<c2/>
<c3/>
<c4/>
</b1>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
namespace pt = boost::property_tree;
int main() {
pt::ptree tree;
// populate tree
tree.put("a.b1", "value1");
tree.put("a.b2", "value2");
tree.put("a.b1.c1", "");
tree.put("a.b1.c2", "");
tree.put("a.b1.c3", "");
tree.put("a.b1.c4", "");
auto options = pt::xml_writer_make_settings<std::string>(' ', 4);
write_xml(std::cout, tree, options);
/*
here I would like to use some sort of get_subtree
function get a subtree of "tree" starting at and including
node "a.b1", and serialize it as XML:
*/
pt::ptree const& subtree = tree.get_child("a.b1");
// option 1
{
pt::ptree fake_root;
fake_root.add_child("b1", subtree);
write_xml(std::cout, fake_root, options);
}
// option 2
{
pt::xml_parser::write_xml_element(std::cout, "b1", subtree, 0, options);
}
}