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

qxmlstreamreader how to skip /end



  • I have a simple xml

    <?xml version="1.0"?>
    <config_file>
    
    <config symbol="A">
    	<val_1>3200</val_1>
    	<val_2>2000</val_2>
    	<val_3>1000</val_3>
    </config>
    
    </config_file>
    

    and a reader

    void XmlReader::Read() {
    
        QFile xml_file(this->filename_);
        xml_file.open( QIODevice::ReadOnly );
        this->xml_.setDevice( &xml_file );
    
        if ( xml_.readNextStartElement() && xml_.name() == "config_file") {
    
            while ( !xml_.atEnd() ) {
    
                std::string field = xml_.name().toString().toStdString();
                xml_.readNext();
    
                std::string value = xml_.text().toString().toStdString();
    
                std::cout << " Next " << field << " " << value << std::endl;
    
    
                xml_.readNextStartElement();
    
            }
        }
    }
    

    The loop prints

    File Found
    Next config_file

    Next config

    Next val_1 3200
    Next val_1

    Next val_2 2000
    Next val_2

    Next val_3 1000
    Next val_3

    Next config

    Next config_file

    So, it seem readNextStartElement() goes to the closing elements as well ( the </...> )

    Is there a way to avoid that? Or is there something else I am doing wrong?



  • Hi @zicx,

    So, it seem readNextStartElement() goes to the closing elements as well ( the </...> )

    Correct. As per the docs for QXmlStreamReader::readNextStartElement:

    Reads until the next start element within the current element.

    (emphasis mine). And also:

    The current element is the element matching the most recently parsed start element of which a matching end element has not yet been reached.

    Is there a way to avoid that?

    Depending on what you want, either check the result of readNextStartElement (returns a boolean). Or, use QXmlStreamReader::skipCurrentElement end of each loop, before calling readNextStartElement.

    Cheers.



  • while (!xml_.atEnd() && !xml_.hasError()) {
                xml_.readNext();
    if (xml_.isStartElement()) {
    if (xml_.name() == QStringLiteral("val_1")) {
    std::cout << "Val1 " << qPrintable(xml_.readElementText())
    }
    if (xml_.name() == QStringLiteral("val_2")) {
    std::cout << "Val2 " << qPrintable(xml_.readElementText())
    }
    if (xml_.name() == QStringLiteral("val_3")) {
    std::cout << "Val3 " << qPrintable(xml_.readElementText())
    }
    }
    


  • @Paul

    "Reads until the next start element within the current element"

    Oh, I misunderstood. I expected it to jump to the next startelement... so it first reads, then I move next, then it reads again and the output was blank because there was no next in that element anymore?

    @VRonin
    The readElementext is quite neat, I like that thanks

    One more question out of curiosity. How do I read out

     <config symbol="A">
    

    the symbol code. I trued with readElementText, but that does not work



  • if (xml_.name() == QStringLiteral("config ")) {
    std::cout << "Val1 " << qPrintable(xml_.attributes().value(QStringLiteral("symbol")))
    }
    


  • @VRonin

    thanks


Log in to reply