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

why no findXmlElement functions?



  • why no findXmlElement functions?

    class MyXmlStreamReader : public QXmlStreamReader
    {
    public:
        MyXmlStreamReader() : QXmlStreamReader() { }
        MyXmlStreamReader(QIODevice *device) : QXmlStreamReader(device) { }
        MyXmlStreamReader(const QByteArray &data) : QXmlStreamReader(data) { }
        MyXmlStreamReader(const QString &data) : QXmlStreamReader(data) { }
        MyXmlStreamReader(const char * data) : QXmlStreamReader(data) { }
        bool findXmlElement(QStringList path) {
            if (path.isEmpty()) {
                return false;
            }
            QString findName = path.at(0);
            while (!atEnd() && !hasError()) {
                readNextStartElement();
                if (findName == name()) {
                    if (path.size() == 1) {
                        return true;
                    } else {
                        return findXmlElement(path.mid(1));
                    }
                } else {
                    skipCurrentElement();
                }
            }
            return false;
        }
        bool findXmlElement(QList<QRegExp> path) { return false; }   // not implemented
    };
    

    Example
    xml-file

    <?xml version="1.0" encoding="UTF-16" ?>
    <persons>
        <person id="1">
            <firstname>John</firstname>
            <surname>Doe</surname>
            <email>john.doe@example.com</email>
            <website>http://en.wikipedia.org/wiki/John_Doe</website>
        </person>
        <person id="2">
            <firstname>Jane</firstname>
            <surname>Doe</surname>
            <email>jane.doe@example.com</email>
            <website>http://en.wikipedia.org/wiki/John_Doe</website>
        </person>
        <person id="3">
            <firstname>Matti</firstname>
            <surname>Meikäläinen</surname>
            <email>matti.meikalainen@example.com</email>
            <website>http://fi.wikipedia.org/wiki/Matti_Meikäläinen</website>
        </person>
    </persons>
    

    code

    int main (int argc, char *argv[]) {
        QApplication a(argc, argv);
        QFile f("file.xml");
        f.open(QIODevice::ReadOnly);
        MyXmlStreamReader xml(&f);
        qDebug() << xml.findXmlElement(QStringList() << "persons" << "person" << "email");
        qDebug() << xml.tokenString() << xml.name() << xml.text();
        return 0;
    }
    


  • @fryn3 said in why no findXmlElement functions?:

    why no findXmlElement functions?

    What sort of an answer are you expecting to this? QXmlStreamReader does not provide "find" functions, it's a forward-only fast stream reader. Use https://doc.qt.io/qt-5/qdomdocument.html (e.g. elementsByTagName()) if you want more advanced capabilities after reading in a whole document. Otherwise you are are writing your own findXmlElement() methods, so what's the issue?



  • @JonB said in why no findXmlElement functions?:

    Use https://doc.qt.io/qt-5/qdomdocument.html (e.g. elementsByTagName()) if you want more advanced capabilities after reading in a whole document.

    The module is not actively maintained anymore. Please use the QXmlStreamReader and QXmlStreamWriter classes in Qt Core instead.

    Later, I will prepare a detailed answer.



  • efficiency point:

     bool findXmlElement(QStringList path){return findXmlElement(path.cbegin(),path.cend());}
    private:
     bool findXmlElement(QStringList::const_iterator pathBegin,QStringList::const_iterator pathEnd) {
            if (pathBegin==pathEnd)
                return false;
            while (!atEnd() && !hasError()) {
                readNextStartElement();
                if (*pathBegin== name()) {
                    if (++pathBegin == pathEnd)
                        return true;
                        return findXmlElement(pathBegin ,pathEnd);
                } else {
                    skipCurrentElement();
                }
            }
            return false;
        }
    

    Functionality point:
    If you have

    <person id="1">
            <firstname>John</firstname>
            <surname>Doe</surname>
            <email>john.doe@example.com</email>
            <website>http://en.wikipedia.org/wiki/John_Doe</website>
        </person>
        <person id="2">
            <firstname>Jane</firstname>
            <surname>Doe</surname>
           <middlename>James</middlename>
            <email>jane.doe@example.com</email>
            <website>http://en.wikipedia.org/wiki/John_Doe</website>
        </person>
    

    Your algorithm will not be able to find QStringList{"person","middlename"}



  • This post is deleted!


  • @fryn3

    The module is not actively maintained anymore. Please use the QXmlStreamReader and QXmlStreamWriter classes in Qt Core instead.

    I don't know if this is something aimed at me? Whatever link you put on "The module" in what you wrote doesn't lead anywhere?





  • @LeLev
    Oh! You mean that all those QXml... and QDom... classes are being withdrawn? No support for reading your entire XML document into a DOM and searching/editing it from there? Seriously? Seems like a retrograde step, Qt provides loads of useful stuff, does it not need such slightly higher-level support for XML?


  • Lifetime Qt Champion

    QtXml is in 'done' state - this doesn't mean it will be removed. It just will not gain any major updates anymore.



  • Just to give you a comparison, bzip2 hasn't received a major update since 2010 and zlib hasn't received any update for more than2 years but they are still the most used compression libraries i can think of. The Qt xml module entered the same stage, it implemented all the features that were considered "in scope" and it woks well as is



  • Good to know. In which case, although the OP rejected my suggestion that he could choose to read the whole document in and do things like QDomDocument::elementsByTagName() because "The module is not actively maintained anymore", that is still an acceptable approach going forward, right?



  • BTW, I've just searched and am delighted to see that Qt does have XPath/XQuery, https://doc.qt.io/qt-5/xmlprocessing.html. It's up to the OP, but I will say that using XPath queries on your XML documents is an order of magnitude nicer than walking the tree in code.

    And for quite separate purposes, I see that also has (at least some) XSLT support, so it gets better & better... :)


Log in to reply