如何使boost属性树打印所有子树然后结束父树

时间:2017-03-28 12:22:37

标签: xml boost boost-propertytree

在下面的代码中,iam试图遍历深度嵌套的地图,我不确定属性树如何解释数据。

它实际上是打印所有父树数据,然后开始打印子树

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

#include <boost/archive/xml_oarchive.hpp>
#include <string>
#include <iostream>
#include <map>
#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <iterator>
    using namespace boost::property_tree;
struct values
{
    std::string a;
    std::string b;
    values():a("milepost"),b("dummyval"){};
    values( std::string ab, std::string bc)
    {
        a=ab;
        b=bc;

    };

    bool operator<(const values& other) const {
         return (a< other.a && b < other.b) ;
         }
    friend std::ostream& operator<<(std::ostream& os, const values& val);

};
std::ostream& operator<< (std::ostream& os , const values& val)
{
  os << val.a <<"\t"<< val.b;
  return os;

}
int main(int argc, const char * argv[]) {

    ptree pt;
    auto& list = pt.add_child("list", ptree{});
    auto& assetlist = pt.add_child("assetlist", ptree{});
    //Create set of types firstly
    std::set<std::string> types ;
    types.insert("et");
    types.insert("pt");

    typedef std::map< int,std::set<std::string> > myGroupsMap;
    typedef std::map<std::string,values>  myWsData;
    typedef std::map< std::string , std::set<myWsData> > myFinalData;
    typedef std::map< int,std::set<myFinalData> > myGroupData;

    myGroupsMap groupTypeMap;

    groupTypeMap.insert(std::make_pair(1, types) );


    groupTypeMap.insert(std::make_pair(2, types) );
    groupTypeMap.insert(std::make_pair(3, types) );
    groupTypeMap.insert(std::make_pair(4, types) );
    groupTypeMap.insert(std::make_pair(5, types) );

    //Create the object of structure
    values a,b,c;

    //Create map and insert the string and its corresponding structure
    myWsData et_Data1,pt_Data2;
    et_Data1.insert(std::make_pair("780256", a));
    et_Data1.insert(std::make_pair("780255", b));
    et_Data1.insert(std::make_pair("780254", c));

    pt_Data2.insert(std::make_pair("780256", a));
    pt_Data2.insert(std::make_pair("780255", b));
    pt_Data2.insert(std::make_pair("780254", c));

    std::set<myWsData> myet_pt_data;
    myet_pt_data.insert(et_Data1);
    myet_pt_data.insert(pt_Data2);

    myFinalData fd , fd1 , fd2 ;
    fd.insert(std::make_pair ("ET",myet_pt_data) );
    fd.insert(std::make_pair ("PT",myet_pt_data) );

    fd1.insert(std::make_pair ("ET",myet_pt_data) );
    fd1.insert(std::make_pair ("PT",myet_pt_data) );

    fd2.insert(std::make_pair ("ET",myet_pt_data) );
    fd2.insert(std::make_pair ("PT",myet_pt_data) );

    std::set<myFinalData> mfd;
    mfd.insert(fd);
    mfd.insert(fd1);
    mfd.insert(fd2);



    myGroupData mygd;
    mygd.insert(std::make_pair (1,mfd) );
    mygd.insert(std::make_pair (2,mfd) );
    mygd.insert(std::make_pair (3,mfd) );

  for (auto &a : mygd)
   {
       for(auto &b:a.second)  //Get the std::set
       {
            for(auto &the_map:b) //get map from set
            {

                list.add("GroupId", a.first);

                list.add("GroupType",the_map.first);
                for(auto &the_set:the_map.second)
                {
                    // the_map takes all values from the set
                    // the_map actual type is std::map<std::string,values>&
                    for (const auto& the_map : the_set)
                    {
       // the_value takes all value of the current map (the_map)
       // the_value actual type is std::pair<std::string,values>&
                            assetlist.add("AssetId",the_map.first);

                            assetlist.add("Milepost",the_map.second.a);
                            assetlist.add("Dummy",the_map.second.b);

                            // list.add("value", map.first)

              //  .add("<xmlattr>.active", true);
                     }
                }
            }
        }
    }


    xml_parser::write_xml(std::cout, pt);

    return 0;
}

输出(摘录):

<?xml version="1.0" encoding="utf-8"?>
<list>
<GroupId>1</GroupId>
<GroupType>ET</GroupType>
<GroupType>PT</GroupType>
<GroupId>2</GroupId>
<GroupType>ET</GroupType>
<GroupType>PT</GroupType>
<GroupId>3</GroupId>
<GroupType>ET</GroupType>
<GroupType>PT</GroupType>
</list>
<assetlist>
  <AssetId>780254</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780255</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780256</AssetId><Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
</assetlist>

预期输出(摘录)

<GroupId>1</GroupId>
<GroupType>ET</GroupType>
<assetlist>
  <AssetId>780254</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780255</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780256</AssetId><Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
</assetlist>
<GroupType>PT</GroupType>
<assetlist>
  <AssetId>780254</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780255</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780256</AssetId><Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
</assetlist>
<GroupId>2</GroupId>
<GroupType>ET</GroupType>
<assetlist>
  <AssetId>780254</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780255</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780256</AssetId><Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
</assetlist>
<GroupType>PT</GroupType>
<assetlist>
  <AssetId>780254</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780255</AssetId>
  <Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
  <AssetId>780256</AssetId><Milepost>milepost</Milepost>
  <Dummy>dummyval</Dummy>
</assetlist>

如何系统地添加它? 代码可以在http://coliru.stacked-crooked.com/a/763741c78d494654

运行

由于 特加斯

1 个答案:

答案 0 :(得分:1)

树包含他们的子树。在关闭父树之前打印父树 打印子树。

您当前的输出和“预期”输出都是无效文档(只能有1个根元素)。

您需要将数据放入单个树中,例如:

ptree pt;
auto& root = pt.add_child("root", ptree{});
auto& list = root.add_child("list", ptree{});
auto& assetlist = root.add_child("assetlist", ptree{});

然后打印以下文档:

<强> Live On Coliru

<?xml version="1.0" encoding="utf-8"?>
<root>
  <list>
    <GroupId>1</GroupId>
    <GroupType>ET</GroupType>
    <GroupId>1</GroupId>
    <GroupType>PT</GroupType>
    <GroupId>2</GroupId>
    <GroupType>ET</GroupType>
    <GroupId>2</GroupId>
    <GroupType>PT</GroupType>
    <GroupId>3</GroupId>
    <GroupType>ET</GroupType>
    <GroupId>3</GroupId>
    <GroupType>PT</GroupType>
  </list>
  <assetlist>
    <AssetId>780254</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780255</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780256</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780254</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780255</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780256</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780254</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780255</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780256</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780254</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780255</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780256</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780254</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780255</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780256</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780254</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780255</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
    <AssetId>780256</AssetId>
    <Milepost>milepost</Milepost>
    <Dummy>dummyval</Dummy>
  </assetlist>
</root>

实际上格式正确的XML:)

更新到评论

如果您想使用grouptypes对资产列表进行分组,那么您需要编写代码来执行此操作吗?

<强> Live On Coliru

ptree pt;
auto& list = pt.add_child("list", ptree{});
//Create set of types firstly
std::set<std::string> types { "et", "pt" };

typedef std::map<std::string,values>  myWsData;
typedef std::map< std::string , std::set<myWsData> > myFinalData;
typedef std::map< int,std::set<myFinalData> > myGroupData;

values a,b,c;

myWsData et_Data1 { { "780256", a }, { "780255", b }, { "780254", c } }, 
         pt_Data2 = et_Data1;

std::set<myWsData> myet_pt_data { et_Data1, pt_Data2 };

myFinalData fd , fd1 = fd, fd2 = fd;

std::set<myFinalData> mfd {
    { { "ET", myet_pt_data }, { "PT", myet_pt_data } },
    { { "ET", myet_pt_data }, { "PT", myet_pt_data } },
    { { "ET", myet_pt_data }, { "PT", myet_pt_data } } };
mfd.insert(fd);
mfd.insert(fd1);
mfd.insert(fd2);

myGroupData mygd;
mygd.insert(std::make_pair (1,mfd) );
mygd.insert(std::make_pair (2,mfd) );
mygd.insert(std::make_pair (3,mfd) );

for (auto &a : mygd)
{
    for(auto &b:a.second)  //Get the std::set
    {
        for(auto &the_map:b) //get map from set
        {
            auto& group = list.add_child("group", {});

            group.add("<xmlattr>.GroupId", a.first);
            group.add("GroupType",the_map.first);

            auto& assetlist = group.add_child("assetlist", ptree{});

            for(auto &the_set:the_map.second)
            {
                // the_map takes all values from the set
                // the_map actual type is std::map<std::string,values>&
                for (const auto& the_map : the_set)
                {
                    // the_value takes all value of the current map (the_map)
                    // the_value actual type is std::pair<std::string,values>&
                    assetlist.add("AssetId",the_map.first);

                    assetlist.add("Milepost",the_map.second.a);
                    assetlist.add("Dummy",the_map.second.b);

                    // assetlist.add("value", map.first)

                    //  .add("<xmlattr>.active", true);
                }
            }

        }
    }
}

xml_parser::write_xml(std::cout, pt);

打印:

<?xml version="1.0" encoding="utf-8"?>
<list>
  <group GroupId="1">
    <GroupType>ET</GroupType>
    <assetlist>
      <AssetId>780254</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780255</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780256</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
    </assetlist>
  </group>
  <group GroupId="1">
    <GroupType>PT</GroupType>
    <assetlist>
      <AssetId>780254</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780255</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780256</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
    </assetlist>
  </group>
  <group GroupId="2">
    <GroupType>ET</GroupType>
    <assetlist>
      <AssetId>780254</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780255</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780256</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
    </assetlist>
  </group>
  <group GroupId="2">
    <GroupType>PT</GroupType>
    <assetlist>
      <AssetId>780254</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780255</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780256</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
    </assetlist>
  </group>
  <group GroupId="3">
    <GroupType>ET</GroupType>
    <assetlist>
      <AssetId>780254</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780255</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780256</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
    </assetlist>
  </group>
  <group GroupId="3">
    <GroupType>PT</GroupType>
    <assetlist>
      <AssetId>780254</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780255</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
      <AssetId>780256</AssetId>
      <Milepost>milepost</Milepost>
      <Dummy>dummyval</Dummy>
    </assetlist>
  </group>
</list>