Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Parse XML document and create/modify elements.



  • I am working on a project which requires parsing and modifying an XML document which is something I have not done before. I need to parse the XML document, check if the required 3 elements exist, if they don't I need to create them, otherwise if they do currently exist I just need to modify the value of it.

    The problem I am having is structuring multiple for loops and if statements to successfully accomplish this. I am aware that what I currently have is flawed as the size of the QDomNodeList is continually growing with size and is therefor stuck in an infinite loop.

    void InstallCert::modifyConfig()
    {
      loadConfig();
    
      QDomElement qRoot = mqConfig.documentElement();
    
      if (!qRoot.isNull())
      {
        QDomNodeList qDomNodeList = qRoot.elementsByTagName("item");
    
        for (int i = 0; i < qDomNodeList.size(); i++)
        {
          QDomElement domElement = qDomNodeList.at(i).toElement();
    
          if (domElement.attribute("name") == "SSL Certificate")
          {
            // Change value
          }
          else
          {
            createItem(qRoot, "SSL Certificate", "string", sCertFileName);
          }
    
          if (domElement.attribute("name") == "SSL Certificate Key")
          {
            // Change value
          }
          else
          {
            createItem(qRoot, "SSL Certificate Key", "string", sKeyFileName);
          }
    
          if (domElement.attribute("name") == "Webserver SSL")
          {
            // Change value
          }
          else
          {
            createItem(qRoot, "Webserver SSL", "bool", "true");
          }
        }
      }
    
      writeConfig();
    }
    

    Is anyone able to help me structure this so that I am able to achieve this?


  • Moderators

    Where is the problem, exactly? You only have one for loop and no nested if statements in the code you posted.



  • @sierdzio Sorry I may not have been clear.

    I have an XML file that initially starts off with one item inside it, but it may in the future have more items within it (dynamic).
    Example:

    <root>
        <item>
              ............
        </item>
    </root>
    

    When my function runs it needs to set 3 values within three items, it needs to parse the XML document and create the three items if they don't already exist, which will always happen on the first time. If the function is triggered for a second time then the XML should already have the 3 new items and it shouldn't have to create them again, but will be able to detect them and modify the values.

    End result:

    <root>
        <item A>
              ............
        </item>
    
        <item B>
              ............
        </item>
    
        <item C>
              ............
        </item>
    
        <item D>
              ............
        </item>
    </root>
    

    I need to try and create this as dynamically as possible as in the future more items may be added to the XML file.


  • Moderators

    The code you wrote seems pretty well suited for this task, then.



  • @sierdzio The current code that I have does not work. The first iteration takes the first item in the XML document and doesn't match true on any of the if statements, therefore creating all 3 items, but what if the XML document already had all four items in it? It would be creating them endlessly as the size of the DomNodeList grows in size.


  • Moderators

    @AaronKelsey said in Parse XML document and create/modify elements.:

    QDomNodeList qDomNodeList = qRoot.elementsByTagName("item");

    You create a copy of the list. It will not grow while the loop is going.


  • Lifetime Qt Champion

    @AaronKelsey
    Hi
    Why not see what you are reading with

    qDebug() << "item.name:" << domElement.attribute("name");
    before the ifs.
    that make its easier to guess why if statements do not trigger/are true
    The debugger is also good for that.



  • @sierdzio Well when using the debugger that current code is continually creating items and does not end.


  • Moderators

    What does createItem() method do, then?



  • @sierdzio It creates an item and appends it to the root

    void InstallCert::createItem(QDomElement& rqItem,
                                 const QString& rsName,
                                 const QString& rsType,
                                 const QString& rsValue)
    {
      QDomElement qItem(mqConfig.createElement("item"));
    
      qItem.setAttribute("argtype", "single");
      qItem.setAttribute("name", rsName);
    
      QDomElement qValue(mqConfig.createElement("value"));
    
      qValue.setAttribute("type", rsType);
    
      QDomText qText(mqConfig.createTextNode(rsValue));
    
      rqItem.appendChild(qItem);
      qItem.appendChild(qValue);
      qValue.appendChild(qText);
    }
    

  • Moderators

    @AaronKelsey said in Parse XML document and create/modify elements.:

    mqConfig

    What is mqConfig, then? My suspicion is that you are calling modifyConfig() indirectly somewhere, and that causes the apparent "loop".


Log in to reply