QDomNodeModel / QXmlQuery

I have prepared an implementation of QAbstractXmlNodeModel class from QtXmlPatterns module which makes it possible to run QXmlQuery-ies on a QDomDocument. I’ve run into problems with QXmlQuery though, because it doesn’t seem to support @Attribute queries either in QXmlQuery::XPath20 or QXmlQuery::XQuery10 mode. I’ve tested it without my custom model and as result got the same dreaded message:

Error XPST0003 in file:///tmp/qdomnodemodel, at line 1, column 13: syntax error, unexpected @, expecting end of file

Has any of the readers experienced similar issues with QXmlQuery? Is this a known limitation of QtXmlPatterns? Other queries seem to be working as expected.

PS. I’m attaching the source code of QDomNodeModel, BSD licensed. I hope QXmlQuery starts working one day 😉

Update 2010/01/08: Yay! It actually works. Qt requires expressions like this: /root/element/@attr instead of /root/element@attr to get attributes. I was under the impression that the latter was correct XPath but it turns out that I was wrong.

qdomnodemodel.tar.gz

17 Comments

  • Hi,

    Great work!
    Except that I can’t get the element when searching with an attribute query.
    For example:
    /optional/@optional
    The query is positive but : QDomElement elem = m.toDomNode(res.current().toNodeModelIndex()).toElement();
    Returns an empty element??

    Could this be fixed pls. ?

    Thanks,
    Frank Vieren

  • Hi,

    I will look into this next week. Could you provide an example XML document in which the problem manifests itself? I have already tested some basic cases and was under the impression that @attr queries work fine.

    Cheers,


    Stan

  • Hi Stan,

    Thx for the quck reply!

    That would be great! Thx.

    Here is the xml file:

    So, I have succes when doing a query like this:

    query.setQuery(“//productdefinition”)

    but when doing this:
    query.setQuery(“//”functionkeys/@title”)

    or with value:
    query.setQuery(“//functionkeys/@title=’Function keys'”);

    are not succesful.
    The evaluator finds results but when validating the dom element the element is null/empty.

    I have tried it further for other attributes and combinations but with no result. Only querying tag elements are succesful.

    I would appreciate it a lot if you could fix it. It is remarkable that qt doesn’t give support for XMLpatterns/XPATH and QDomDocument in a direct way!
    So your work is very usefull!

    BTW I’m using Qt 4.7 and mingw as build environment.

    Thanks in advance,
    Have a nice weekend.
    Frank

    frank.vieren@telenet.be
    frank.vieren@barco.com

  • Hi Stan,

    I’m not able to copy past my XML file in the message but if you provide me your email address I can send it to you.

    Thanks again for looking at this.

    Best regards,
    Frank

  • Wow, it’s quite interesting as I had the exact opposite problem. Or maybe not …. Are you using square brackets literally or to denote that attribute query is optional?

  • Hi Stan,

    You really need the square brackets when the query is based on the attribute.
    Thus exactly as I stated before:
    //functionkeys[@title]

    I also did something like this:
    //functionKeys[@value=’F1′]

    with succes.

    So far I have not encountered anymore problems.

    Best regards,
    Frank

  • Good day!

    Your module is very good. But can You upgrade QDomNodeModel to support namespace-s ?

    You – my last hope. Thanks! =)

    • It seems feasible, implementing the missing namespaceBindings() method should do the trick. Can you provide a unit test for me? Then, I’ll give it a go.

  • Hi!

    To support namespaces I made small upgrade.
    Just replace n.nodeName() with n.localName() in funcion QDomNodeModel::name(…).
    Don’t forget to set namespaceProcessing when seting content for QDomDocument.

  • Hi,

    No more problems with the parsing but as my XML file gets longer the queries take much more time to get resolved. Any remedy? The file is 94kbytes (500 lines…)

    thanks,
    Best regards,
    Frank

    • Hi

      Appreciate your efforts here, really had my hopes up.

      I have to agree with Frank, unfortunately this is very very slow, possibly something like O^N performance.

      Either the QAbstractXmlModel is poorly designed, or something with your implementation. But having had played a bit with the filetree example, I think the QAbstractXmlModel has a major flaw. Unfortunately my profiling skills are poor and I don’t know the best way to diagnose the cause – any suggestions?

      Quick (< 1 second):

      // 300kb file with 100s of nodes
      char* filename = "C:\Development\Projects\Looksie\Documentation\MockupGenerator\Language Tools.bmml";

      QXmlNamePool pool;
      QXmlQuery query(pool);
      query.bindVariable("tree", QVariant(QString(filename)));
      query.setQuery("doc($tree)//@controlTypeID/string()");
      QString s;
      query.evaluateTo(&s);
      qDebug() << s;

      Slow ( ~ 10 seconds):

      QXmlNamePool pool;
      QDomNodeModel model(pool, m_currentDocument);
      QXmlQuery query(pool);
      query.bindVariable("doc", model.fromDomNode(mockupElement));
      query.setQuery("$doc//@controlTypeID/string()");
      QXmlResultItems items;
      query.evaluateTo(&items);

      • Very good. I was about to suggest what amounts to pretty much the same thing – do an initial pass over whole tree and enumerate all nodes assigning them increasing ordinals and then just compare ordinals. Line/column number approach is even better because it doesn’t require fiddling with QDomNode trying to put an ordinal in there 🙂 Although it makes me wonder what will happen when you start inserting nodes dynamically…

        • For my use the Dom is always read-only so not an issue.
          Once again thanks for your good work.

          Crazy that QDom* doesn’t already include query support…


Leave a Reply to admin Cancel reply

Your email address will not be published. Required fields are marked *