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

Append nodes to an XML file



  • Hi all,

    I have xml file which looks like this:

    <!DOCTYPE patientDetails>
    <subject_details>
     <Name>Name1</Name>
     <Surname>Surname1</Surname>
     <Patient_ID>PID01</Patient_ID>
     <Date>01/01/2000 00:00</Date>
     <Clinician_Note>some note for testing</Clinician_Note>
    </subject_details>
    

    I need to modify and append more nodes to the above xml.

    For ex. My new node to be added to the above file looks like this:

    <settings>
     <Current>35</Current>
    </settings>
    

    I tried doing this:

        QString  errorMsg;
        int errorLine,errorColumn;
    
        QDomDocument document;
    
        QString path = QCoreApplication::applicationDirPath()+"/data/"+"PID02"+".xml";
    
        qDebug()<<path;
        //Load the file
        QFile file(path);
        if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
        {
        qDebug()<<"failed to open file";
        return -1;
        }
    
        else
        {
            if(!document.setContent(&file,&errorMsg, &errorLine, &errorColumn))
            {
                qDebug () << file<<errorMsg << errorLine << errorColumn;
                qDebug() << "Failed to load the file for reading.";
            }
    
            file.close();
        }
    
        document.setContent(&file);
    
        QDomElement root = document.documentElement();
    
        QDomElement newTag = document.createElement(QString("Settings"));
        QDomElement newCurrTag = document.createElement(QString("Current"));
        QDomText newCurrVal = document.createTextNode(QString("45"));
        newCurrTag.appendChild(newCurrVal);
        newTag.appendChild(newCurrTag);
        root.appendChild(newTag);
    
        QTextStream output(&file);
        output << document.toString();
    
    
        file.close();
    
    

    EDITED
    I cant write new nodes to my file and the consol says: ReadOnly Device

    What I'm doing wrong here?

    Thanks


  • Lifetime Qt Champion

    Try to pass a proper xml - it should start with '<?xml version="1.0"?>'



  • @Christian-Ehrlicher

    I tried with a modified xml but the same issue.

    This error comes only when I open the file to Append:

    QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text
    

    But if it's just for ReadWrite

    QIODevice::ReadWrite |  QIODevice::Text
    

    Atleast file is leading. Though I can't change the xml file..


  • Lifetime Qt Champion

    Did not notice it - for sure QIODevice::Append will not work. So what's your actual output?



  • @Christian-Ehrlicher

    If I do QIODevice::ReadWrite | QIODevice::Text, file loading ok. But I cant write new nodes to it..

    Consol says ReadOnly device

    Any idea where I'm wrong?



  • @russjohn834
    If I understand what you are trying to do correctly, we have gone through this many times in this forum. If your goal is to update XML in a file, you don't open the file for append or read-write or anything like that. You open the file read-only, read it all in, close it. Make your changes to the in-memory document. Then open the file for overwrite, write all content, close file. (Or write to a new file and then delete/rename.) Your code will contain neither QIODevice::ReadWrite nor QIODevice::Append.


  • Lifetime Qt Champion

    @russjohn834 said in Append nodes to an XML file:
    Hi
    ......
    root.appendChild(newTag);
    there is missing a file open here ? ( you call close higher up but i dont see an open for write ?)
    QTextStream output(&file);
    output << document.toString();
    file.close();


  • Banned

    This post is deleted!


  • Thank you @mrjj @JonB
    I can now append a new node to my file, I did as follows:

        if(!file.open(QIODevice::ReadOnly  | QIODevice::Text))
            {
                qDebug () << "Error saving XML file...."; 
                file.close();
            }
    
            document.setContent(&file);
            QDomElement root = document.documentElement();
            file.close();
    
            QDomElement newTag = document.createElement(QString("Settings"));
            QDomElement newCurrTag = document.createElement(QString("Current"));
            QDomText newCurrVal = document.createTextNode(QString("45"));
            newCurrTag.appendChild(newCurrVal);
            newTag.appendChild(newCurrTag);
            root.appendChild(newTag);
    
            file.open(QIODevice::WriteOnly | QIODevice::Text);
            QTextStream output(&file);
            output << document.toString();
            file.close();
    
    
    


  • @russjohn834
    That's much better!

    Now just a minor picky for good code.

        if(!file.open(QIODevice::ReadOnly  | QIODevice::Text))
            {
                qDebug () << "Error saving XML file...."; 
                file.close();
            }
        ...
    

    Don't forget to put some kind of return at the end of that error case so it does not continue into the "opened" code. And (unless you know better for QFile) don't file.close() if you are inside an if (!file.open()), because the file never got opened! Plus, change all that indentation after the if's }, so it doesn't look like it's all still inside the if :)



  • @JonB Thank you for the feedback :)


Log in to reply