Search code examples
c++xmltinyxml2

Updating Data in tiny Xml element


My question is: is it possible to change the data in an xml element?

What i want to do is change the data in the element depending on what button is pressed. I currently have it reading and writing to the xml file working but i want to change it to, write a new element first time round and then after that edit the element as it currently just keeps writing a new element each time.

This is my current code for writing the new element

if (doc.LoadFile(XMLDOC) == tinyxml2::XML_SUCCESS){
    //Get Root Node
    tinyxml2::XMLElement* rootNode = doc.FirstChildElement();//Assets
    //Get Next Node
    tinyxml2::XMLElement* childNode = rootNode->FirstChildElement();//imagePaths
    //Temp Element 
    tinyxml2::XMLElement* temp = nullptr;
    tinyxml2::XMLElement* temp2 = childNode->FirstChildElement();//path

    while (temp2 != nullptr){
        temp = temp2;
        temp2 = temp2->NextSiblingElement("path");
    }
    if (temp != nullptr){
        //write the text
        tinyxml2::XMLComment* newComment = doc.NewComment("Selected Player");
        tinyxml2::XMLElement* newElement = doc.NewElement("path");

            //get text passed in 
            newElement->SetText(choice.c_str());

            newElement->SetAttribute("name", "selected_player");
            childNode->InsertAfterChild(temp, newComment);
            childNode->InsertAfterChild(newComment, newElement);

    }
    //doc.Print();
    doc.SaveFile(XMLDOC);
    }
    else{
        std::cout << "Could Not Load XML Document : %s" << XMLDOC << std::endl;
    }
}

Thanks for helping in advanced


Solution

  • I'm not 100% sure what the desired behavior you want. Here is a code sample based off of your question code sample:

    #include "tinyxml2.h"
    #include <iostream>
    #include <string>
    
    #define XMLDOC "test.xml"
    
    std::string choice = "New Text";
    
    int main()
    {
       tinyxml2::XMLDocument doc;
       if (doc.LoadFile(XMLDOC) == tinyxml2::XML_SUCCESS){
          //Get Root Node
          tinyxml2::XMLElement* rootNode = doc.FirstChildElement();//Assets
          //Get Next Node
          tinyxml2::XMLElement* childNode = rootNode->FirstChildElement();//imagePaths
          //Path Node
          tinyxml2::XMLElement* pathNode = childNode->FirstChildElement();//path
    
          if (pathNode == nullptr){
             //write the text
             tinyxml2::XMLComment* newComment = doc.NewComment("Selected Player");
             tinyxml2::XMLElement* newElement = doc.NewElement("path");
    
             newElement->SetAttribute("name", "selected_player");
             newElement->SetText(choice.c_str());
    
             childNode->InsertFirstChild(newComment);
             childNode->InsertAfterChild(newComment, newElement);
          }
          else{
             pathNode->SetText(choice.c_str());
          }
          doc.SaveFile(XMLDOC);
       }
       else{
          std::cout << "Could Not Load XML Document : " << XMLDOC << std::endl;
       }
    }
    

    Given a XML file that looks like this:

    <Assets>
    <ImagePaths>
    </ImagePaths>
    </Assets>
    

    After running it would look like this:

    <Assets>
    <ImagePaths>
        <!--Selected Player-->
        <path name="selected_player">New Text</path>
    </ImagePaths>
    </Assets>
    

    And if you run the program again you get just the single path node with the text that your choice string contains.

    Hope that helps!