从boost::property_tree::ptree::迭代器获取ptree

Getting the ptree from boost::property_tree::ptree::iterator

本文关键字:ptree 迭代器 tree 获取 boost property      更新时间:2023-10-16

我有一段代码在boost属性树(XML)上进行迭代
我需要当前节点的ptree,而不是该节点的子节点。

更新

xml树

<node id="A.html">
    <subnode> child A1 </subnode>
    <subnode> child A2 </subnode>
</node>
<node id="B.html">
    <subnode> child B1 </subnode>
    <subnode> child B2 </subnode>
</node>

识别码

void parse_tree(ptree& pt, std::string key)
{
    string nkey;
    if (!key.empty())
    nkey = key + ".";
    ptree::const_iterator end = pt.end();
    for(ptree::iterator it = pt.begin(); it != end; ++it){
        //if the node's id is a .html filname, save the node to file
        string id = it->second.get("<xmlattr>.id","");
        if(id.find("B.html") != std::string::npos){  //Let's just test for "B.html"
            write_xml("test.html", pt);           //saves entire tree
            write_xml("test.html", it->second);   //saves only children of the node
        }
        parse_tree(it->second, nkey + it->first); //recursion
    }
}

使用write_xml("test.html",pt)的结果

(我们得到整个树,我们只想要节点)

<node id="A.html">
    <subnode> child A1 </subnode>
    <subnode> child A2 </subnode>
</node>
<node id="B.html">
    <subnode> child B1 </subnode>
    <subnode> child B2 </subnode>
</node>

使用write_xml("test.html",it->second)的结果

(我们没有父节点。只有子节点)

<subnode> child B1 </subnode>
<subnode> child B2 </subnode>

所需结果

(我们想要节点,它是子节点,..就像这样)

<node id="B.html">
    <subnode> child B1 </subnode>
    <subnode> child B2 </subnode>
</node>

更新2

根据评论/更新的问题重写。

有两种方法。

  1. 您可以使用未记录的函数write_xml_element来编写单个元素(使用键作为元素名称):

        // write the single element: (undocumented API)
        boost::property_tree::xml_parser::write_xml_element(
                std::cout, it->first, it->second,
                0, settings
            );
    
  2. 或者您可以使用单个子创建一个新的ptree对象

        ptree tmp;
        tmp.add_child(it->first, it->second);
        write_xml(std::cout, tmp, settings);
    

在Coliru上直播

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <fstream>
#include <iostream>
using namespace boost::property_tree;

void parse_tree(ptree& pt, std::string key)
{
    std::string nkey;
    auto settings = xml_parser::xml_writer_make_settings<std::string>('t', 1);
    if (!key.empty()) {
        nkey = key + ".";
    }
    ptree::const_iterator end = pt.end();
    for(ptree::iterator it = pt.begin(); it != end; ++it)
    {
        //if the node's id an .html filname, save the node to file
        std::string id = it->second.get("<xmlattr>.id","");
        if (id.find(key) != std::string::npos) {
            // write the single element: (undocumented API)
            boost::property_tree::xml_parser::write_xml_element(
                    std::cout, it->first, it->second,
                    0, settings
                );
            // or: create a new pt with the single child
            std::cout << "n==========================nn";
            ptree tmp;
            tmp.add_child(it->first, it->second);
            write_xml(std::cout, tmp, settings);
        }
        parse_tree(it->second, nkey + it->first); //recursion
    }
}
int main() {
    ptree pt;
    read_xml("input.txt", pt);
    parse_tree(pt, "B");
}

输出:

<node id="B.html">
    <subnode> child B1 </subnode>
    <subnode> child B2 </subnode>
</node>
==========================
<?xml version="1.0" encoding="utf-8"?>
<node id="B.html">    
    <subnode> child B1 </subnode>
    <subnode> child B2 </subnode>
</node>