简体   繁体   中英

How to add a node in front of boost property_tree

I have a xml

<MyXML>
    <Tag2>2</Tag2>
    <Tag3>3</Tag2>
    <Tag4>4</Tag3>
</MyXML>

and read it into boost::property_tree::ptree xmlroot using boost::property_tree::read_xml

Now if I add a new node by

xmlroot.add("MyXML.Tag1", "1");

This new node will add to back of existing tags. After boost::property_tree::write_xml, I get

<MyXML>
    <Tag2>2</Tag2>
    <Tag3>3</Tag2>
    <Tag4>4</Tag3>
    <Tag1>1</Tag1>
</MyXML>

Is there a way to insert new node in front of Tag2?

It's possible, but it's outside of scope of standard accessors like get and add so one has to go the longer and more cumbersome way of iterators. Basically you need to get an iterator for your node and use insert or push_front insert a new node at required place.

Full example.:

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <string>
#include <exception>
#include <iostream>
namespace pt = boost::property_tree;

int main()
{
    try
    {
        std::string xml_content =
"<MyXML> \
    <Tag2>2</Tag2> \
    <Tag3>3</Tag2> \
    <Tag4>4</Tag3> \
</MyXML>";
        std::stringstream xml (xml_content);
        pt::ptree tree;
        pt::read_xml (xml, tree);
        /* ~~~~ KEY STUFF ~~~~ */
        auto root = tree.find("MyXML");
        root->second.push_front({"NewTag", decltype(tree)("1")});
        /* ~~~~ KEY STUFF ~~~~ */
        pt::write_xml (std::cout, tree);
    }
    catch (std::exception &e)
    {
        std::cout << "Error: " << e.what() << "\n";
    }
    return 0;
}

Key stuff explained:

    auto root = tree.find("MyXML");
    root->second.push_front({"NewTag", decltype(tree)("1")});

Ok, so 1st line is a no brainer, we need to get our "work" node.

Second line uses push_front , which inserts a new node at the front of the caller. But out caller is at the second field of the iterator, which is the result of find("MyXML") .

Then push_front expects a pair of key and self_type . I used brace initialization for pair, and a string literal for key. Creating a new node of matching type is a little bit more tricky, since the constructor using value is marked as explicit. So, one has to use it's type. I got it using decltype of the tree .

If anything can be simplified I happily welcome all improvements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM