Search code examples
c++xmlboostboost-propertytree

Adding a sub child to boost ptree


Lets say I am aiming to create an xml in the following form:

<main>
<elements>
    <element name="elem1"><temp/>
    </element>
    <element name="elem2"><temp/>
    </element>
</elements>
</main>

I have the following code:

ptree pt;
pt.put("main","");

ptree temp1;
temp1.put("element","");
temp1.put("element.<xmlattr>.name","elem1");
temp1.put("element.temp");

ptree temp2;
temp2.put("element","");
temp2.put("element.<xmlattr>.name","elem2");
temp2.put("element.temp");

//temp1 represents the 1st <element>...</element>
//temp2 represents the 1st <element>...</element>

//Add temp1 and temp2 to <main> under <elements>

I would assume the following would work:

pt.add_child("main.elements",temp1);
pt.add_child("main.elements",temp2);

However this generates the following xml:

<main>
<elements>
    <element name="elem1"><temp/>
    </element>
</elements>
<elements>
    <element name="elem2"><temp/>
    </element>
<elements>
</main>

I was able to get the required xml file by making my temp1 in the following form:

temp1.put("<xmlattr>.name","elem1");
temp1.put("temp","");
temp2.put("<xmlattr>.name","elem2");
temp2.put("temp","");
pt.add_child("main.elements.element",temp1);
pt.add_child("main.elements.element",temp2);

Is there a way I can work with my initial temp1 and temp2 nodes to get the desired xml structure?


Solution

  • Your situation is a bit suboptimal (and I'd very much favour the working snippet you gave).

    Here's what would work:

    pt.add_child("main.elements.element", temp1.get_child("element"));
    pt.add_child("main.elements.element", temp2.get_child("element"));
    

    Live On Coliru

    #include <boost/property_tree/xml_parser.hpp>
    #include <iostream>
    
    using boost::property_tree::ptree;
    
    int main() {
        ptree temp1;
        temp1.put("element.<xmlattr>.name","elem1");
        temp1.put_child("element.temp", {});
    
        ptree temp2;
        temp2.put("element.<xmlattr>.name","elem2");
        temp2.put("element.temp", "");
    
        //Add temp1 and temp2 to <main> under <elements>
        ptree pt;
        pt.add_child("main.elements.element", temp1.get_child("element"));
        pt.add_child("main.elements.element", temp2.get_child("element"));
        write_xml(std::cout, pt, boost::property_tree::xml_writer_make_settings<std::string>(' ', 4, "utf-8"));
    }
    

    Prints

    <?xml version="1.0" encoding="utf-8"?>
    <main>
        <elements>
            <element name="elem1">
                <temp/>
            </element>
            <element name="elem2">
                <temp/>
            </element>
        </elements>
    </main>