Search code examples
c++xmlxml-parsingpugixml

Add line to .xml using pugixml and C++


I have an XML document that I need to write to using pugixml and Cpp. Part of my XML document looks like this:

line 4                   <people>
line 5                   <guys>
line 6                   <dude name="man" delay="1" life="0.75" score="5" />
line 7                   <dude name="man" delay="1" life="0.75" score="5" />
line 8                   <dude name="man" delay="1" life="0.75" score="5" />
line 9                   <dude name="man" delay="1" life="0.75" score="5" />
line 10                  <dude name="man" delay="1" life="0.75" score="5" />
line 11                  </guys>
line 12                   <guys>
line 13                   <dude name="man" delay="1" life="0.75" score="5" />
line 14                   <dude name="man" delay="1" life="0.75" score="5" />
line 15                   <dude name="man" delay="1" life="0.75" score="5" />
line 16                   <dude name="man" delay="1" life="0.75" score="5" />
line 17                  <dude name="man" delay="1" life="0.75" score="5" />
line 18                  </guys>
                         </people>

How would I add another (dude name="man" delay="1" life="0.75" score="5") line after line 13, moving all the other lines down one in my .xml file?

I am trying....

//get xml object
  pugi::xml_document doc;
//load xml file
  doc.load_file(pathToFile.c_str);
//edit file
  doc.child("people").child("guys").append_copy(doc.child("people").child("guys").child("dude"));
//save file
doc.save_file(pathToFile.c_str);

But it doesn't appear to be working. Any ideas?


Solution

  • Use XPath it becomes much easier and readable without all that child() function calls.

    To insert in the first row moving all other lines bellow use prepend_copy function.

    This works here with your example xml:

    pugi::xml_document doc;
    
    //load xml file
    doc.load_file(pathToFile);
    
    pugi::xpath_node nodeToInsert;
    pugi::xpath_node nodeParent;
    
    try
    {
        nodeToInsert = doc.select_single_node("/people/guys[2]/dude[1]");
        nodeParent = doc.select_single_node("/people/guys[2]");
    }
    
    catch (const pugi::xpath_exception& e)
    {
        cerr << "error " << e.what() << endl;
        return -1;
    }
    
    nodeParent.node().prepend_copy(nodeToInsert.node()); // insert at the first row
    
    //save file
    std::cout << "Saving result: " << doc.save_file("output.xml") << std::endl;