Reputation: 567
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?
Upvotes: 0
Views: 1299
Reputation: 16070
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.
Upvotes: 2