c++xmlqtqtxml

C++/Qt QDomDocument: iterate over all XML Tags


my Problem is, I have a large XML-styled File represented as QDomDocument and I need to access certain Tags on multiple locations in the XML

My XML looks like this

<Mat1>
    <Name>Mat_1</Name>
    <Properties>
        <Size>10</Size>
        <SizeMod>G</SizeMod>
    </Properties>
</Mat1>
<Mat2>
    <Name>Mat_2</Name>
    <Properties>
        <Size>15</Size>
        <SizeMod>k</SizeMod>
    </Properties>
</Mat2>

And I need to access all occurrences of "SizeMod" and "Size". The problem is the layout of the file might change regularly in the future and I want my code to work with all versions of the File.

At the moment I just iterate over all childNodes with multiple for-loops until I reach the needed depth and then I check with an if-statement, if I am at the right node.

But that seems like a bad way to do it.


Solution

  • As @hank commented, you should use QDomDocument::elementsByTagName(const QString &tagname) to get the elements in the document with the name tagname.

    Then, iterate over the nodes to get each QDomNode. Finally, convert the QDomNode into a QDomElement.

    Example where we're printing the element's text and the tag name:

    #include <QtXml>
    #include <QtCore>
    
    int main()
    {
        QFile file(":/myxml.xml");
    
        file.open(QFile::ReadOnly|QFile::Text);
    
        QDomDocument dom;
        QString error;
    
        int line, column;
    
        if(!dom.setContent(&file, &error, &line, &column)) {
            qDebug() << "Error:" << error << "in line " << line << "column" << column;
            return -1;
        }
    
        QDomNodeList nodes = dom.elementsByTagName("Size");
        for(int i = 0; i < nodes.count(); i++)
        {
            QDomNode elm = nodes.at(i);
            if(elm.isElement())
            {
                qDebug() << elm.toElement().tagName()
                         << " = "
                         <<  elm.toElement().text();
            }
        }
    
        nodes = dom.elementsByTagName("SizeMod");
        for(int i = 0; i < nodes.count(); i++)
        {
            QDomNode elm = nodes.at(i);
            if(elm.isElement())
            {
                qDebug() << elm.toElement().tagName()
                         << " = "
                         << elm.toElement().text();
            }
        }
    
        return 0;
    }