I will repeat: there is no xml parser/library in Boost.
What you are (ab)using is Boost Property Tree. As you found, it's a "property tree" library, meaning it can do some things. Including writing and reading property trees.
If you want general purpose XML stuff, consider using an XML library (What XML parser should I use in C++?).
Without further ado:
Live On Coliru
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
int main() {
using boost::property_tree::ptree;
ptree pt;
{
ptree children; children.add("Foo", "bar");
pt.add_child("child", children);
pt.add_child("child", children).put("MARK","so we know it's the second");
}
// Output
boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
//boost::property_tree::write_xml(std::cout, pt, settings);
auto child1 = std::find_if(pt.begin(), pt.end(), [](auto& node) { return node.first == "child"; });
auto child2 = std::find_if(std::next(child1), pt.end(), [](auto& node) { return node.first == "child"; });
if (child2 != pt.end())
{
boost::property_tree::write_xml(std::cout, child2->second, settings);
ptree newChildren("Foo");
child2->second.put("Sub.Foo", newChildren.data()).put("BYE", "ALL DONE"); // <-- Access second element?
boost::property_tree::write_xml(std::cout << "\n\nAFTER EDITING:\n", child2->second, settings);
}
}
Prints:
<?xml version="1.0" encoding="utf-8"?>
<Foo>bar</Foo>
<MARK>so we know it's the second</MARK>
AFTER EDITING:
<?xml version="1.0" encoding="utf-8"?>
<Foo>bar</Foo>
<MARK>so we know it's the second</MARK>
<Sub>
<Foo>
Foo
<BYE>ALL DONE</BYE>
</Foo>
</Sub>
UPDATE
Improving the style with a helper function:
Live On Coliru
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
template <typename Tree, typename Out>
Out find_all(Tree& pt, typename Tree::path_type path, Out out) {
if (path.empty()) {
*out++ = pt;
return out;
}
auto head = path.reduce();
for (auto& child : pt)
if (child.first == head)
out = find_all(child.second, path, out);
return out;
}
int main() {
using boost::property_tree::ptree;
ptree pt;
{
ptree children; children.add("Foo", "bar");
pt.add_child("child", children);
pt.add_child("child", children).put("MARK","so we know it's the second");
}
// Output
boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
//boost::property_tree::write_xml(std::cout, pt, settings);
std::vector<std::reference_wrapper<ptree> > matches;
find_all(pt, "child", back_inserter(matches));
ptree& child2 = matches.at(1);
child2.put("BYE", "ALL DONE");
boost::property_tree::write_xml(std::cout, child2, settings);
}
Prints
<?xml version="1.0" encoding="utf-8"?>
<Foo>bar</Foo>
<MARK>so we know it's the second</MARK>
<BYE>ALL DONE</BYE>