XSL-T and Qt

September 10, 2008

A couple of weeks ago, I merged the development branch for XSL-T into our main line, heading for Qt 4.5. The idea is that Qt will carry an XSL-T 2.0 implementation with as usual being cross-platform, having solid documentation, and easy of use.

Using it is should straightforward. Either on the command line:

xmlpatterns yourStylesheet.xsl yourInputDocument -param myParam=myValue

Or using the C++ API[1]:

QXmlQuery myQuery(QXmlQuery::XSLT20);
myQuery.bindVariable("myParam", QVariant("myValue");
myQuery.setQuery("http://example.com/myStylesheet.xsl");
QFile out("outFile.xml");
out.open(QIODevice::WriteOnly);

myQuery.evaluateTo(&out);

See the documentation for the QXmlQuery class on the overloads available for setQuery() and evaluateTo(), for instance.

However, due to the beast XSL-T 2.0 is — I agree that it’s larger than XQuery — we’ve decided to do this according to the “release early release often” approach. The first, in Qt 4.5, will carry a subset, and subsequently be complemented in Qt 4.6. The current status is documented in the main page for the QtXmlPatterns module, which can be viewed in the documentation snapshot.

Therefore, while the current implementation probably falls short on more complex applications(such as Docbook XSL), it can run simpler things, users can plan ahead, and we trolls can receive feedback on what features/APIs that are missing, and what needs focus. So feel free to do that: send a mail to qt-bugs@trolltech.com, or say hello on IRC(FransE, on Free Node).

The code is accessible through the Qt snapshots.

What is XSL-T anyway?

XSL-T is a programming language for transforming XML into XML, HTML or text. Some implementations,Β  such as QtXmlPatterns or Saxon, provides mechanisms to map XML to other data sources and hence widens the scope of the language by letting the XML act as an abstract interface. Wikipedia has a good article on XSL-T. Version 2.0 of XSL-T extends the language heavily by putting a rigid type system and data model in the backbone, and adds many features that was a pain to miss when programming in XSL-T 1.0. XSL-T 2.0 use XPath 2.0, and shares the same large function library as XQuery.

1.

Over time, Java bindings through QtJambi and ECMAScript bindings through QtScript, will likely arrive.

21 Responses to “XSL-T and Qt”

  1. Bernhard Friedreich Says:

    hell yes! those are great news πŸ™‚

    The only thing I’m now missing on the Xml side is Validation… something like XSD.. would be great to see that too

    Looking forward to Qt 4.5,

    Bernhard

  2. Dominic Says:

    I love you for this. Add a similarly easy XPath evaluator and a XML Schema validator and I will raise a monument for you. Simple tools for XML processing on the command line that are installed on virtually any Linux machine is something I have been waiting for for quite some time.

  3. Chris Hills Says:

    Does this mean that QWebKit will now be able to display XML documents that use an XSLT document for presentation?

  4. englich Says:

    Dominic:
    Qt 4.4 already has an XPath 2.0 evaluator, here’s the code for it:

    QXmlQuery query;
    query.setQuery(“doc(‘yourDoc.xml’)/your/XPath[1]”);
    query.evaluateTo(…);

    Chris:
    I’ve been talking with my colleague & Webkit dude Simon Hausmann about integrating XSL-T and our plan was to do this for Qt 4.5, but we’re too overloaded with work already that this most likely will be postponed. But at some point the two pieces will definitely be glued together. This should be doable with public API, so anyone is welcome to try it out πŸ™‚ Of course, this XSL-T support would require Qt, so it would only be available for QtWebkit based applications/libraries.

  5. Sebastian Sauer Says:

    > what features/APIs that are missing

    Cause you asked πŸ™‚

    With libxslt it is easy to register own extensions what is an essential feature to be able to put more complex handlers in place for the stylesheets and extend what the xslt-specs provide with own functionality.

    That is done by using the xsltRegisterExtModuleFull to register the own module and xsltRegisterExtModuleElement to register handlers for own xsl-tags.

    Think here of being e.g. able to define a and tag to integrate e.g. KArchive to transparently process zip-archives or to allow to deal with remote document()-sources, etc.

  6. Sebastian Sauer Says:

    eh, seems my last sentence got partly eaten. Second try;

    Think here of being e.g. able to define a <zip/> and <unzip/> tag to integrate e.g. KArchive to transparently process zip-archives or <kio/> to allow to deal with remote document()-sources, etc.

  7. Michael "C++" Howell Says:

    Line 2 in your C++ api example should be:
    myQuery.bindVariable(“myParam”, QVariant(“myValue”));
    instead of:
    myQuery.bindVariable(“myParam”, QVariant(“myValue”);

    Mis-match parenthesis.

  8. Chris Hills Says:

    @englich

    Thanks, that is good news indeed!

  9. John Snelson Says:

    Congratulations Frans! It seems we’re destined to be working on the same functionality in different products, since I’ve been adding XSLT 2.0 support to XQilla as well ;-).

  10. Patrik Says:

    With libxslt i use a
    error handler like:
    void qt_libxml_error_handler(void *ctx, const char *msg, …)
    xsltSetGenericErrorFunc(&xslt_errors,\ qt_libxml_error_handler);
    xmlSetGenericErrorFunc(&xslt_errors, \
    qt_libxml_error_handler);
    xsltSetGenericDebugFunc(&xslt_errors, \
    qt_libxml_error_handler);

    How its possibel to make the same on QXmlQuery?
    I found this utils to write or debug xsltfile.

  11. englich Says:

    @Patrik:

    You’ll need to:
    1. Subclass QAbstractMessageHandler
    2. Call QXmlQuery::setMessageHandler(&yourMessageHandler);

    @John:
    I know πŸ™‚ I actually went for the approach of rewriting XSL-T into XQuery code, but I’ve started to doubt it more and more as I’ve been progressing.. My plan is to write a paper on my implementation approach, but it will have to wait at least a couple of months.

  12. Patrik Says:

    Great tanks…
    on your sample:

    QXmlQuery myQuery(QXmlQuery::XSLT20);
    myQuery.bindVariable(“myParam”, QVariant(“myValue”);
    myQuery.setQuery(“style.xsl”);
    QFile out(“outFile.xml”);
    out.open(QIODevice::WriteOnly);

    You dont take a xml data? or data is on xsl..
    if i take data from mysql i write a xml tree and one “template” xsl and union this dwo file to outFile and how prepend xml data? other setQuery?
    I use gnome libxslt to union data two file + params in last 6 year.. But i like to use QXmlQuery::XSLT20 to make cristal report similar db query print.

  13. englich Says:

    Patrik:

    Yes, you’ll want to call QXmlQuery::setFocus(), to supply your input document.

    Feel free to jump onto the qt-interest mailinglist; it’s great for asking technical questions on Qt.

  14. Guido Seifert Says:

    I like the whole QtXmlPatterns stuff. Though I must say until after the “XQuery & Qt: Strong Tools for your XML Challenges” session during devDays in Munich it somehow escaped my attention. I was probably too used to use the QtXml module. Now I wonder if it would be possible to ‘join’ QtXml and QtXmlPatterns. Especially interesting would be the possibility to pass a QDomDocument to a QXmlQuery and get a QDomNode or a list of QDomNodes as result.

  15. englich Says:

    Guido:
    Glad that you liked it πŸ™‚

    We currently don’t have glue code between QDom and QtXmlPatterns because of legacy reasons: QDom has bugs that we can’t fix due to historical reasons, and our plan is instead to supply new and better solutions(for instance, we’re pondering the idea of a new tree API). But it makes indeed conceptually sense to be able to use XQuery/XSL-T on top of QDomNode.

    What your application’s working flow that creates the need for this feature? For instance, would it be possible to do all processing in XQuery/XSL-T, or why is the reason to that the data needs to be in a QDom instance?

    • Mark Says:

      Hello Englich,

      I am creating an authoring tool and I would also like to transform memory bound dom trees rather than xml files. I will be transforming a subsection of an QDomDocument for display and editing, transforming it back into the original schema, and replacing the original subsection. All of this will be done in memory and if I can avoid writing to disk I would prefer it.

      I am sure I will have an implementation complete by 4.6, but I look forward to new tools to address my use case. I love refactoring that simplifies my design.

      Thanks a bunch,
      Mark

  16. Guido Seifert Says:

    Hi Frans,
    XQuery is great when you need to read data from certain nodes in an xml document. XQuery is often compared with SQL for databases. Unfortuantely in this comparison it implements only the ‘SELECT’ statement, but not the ‘UPDATE’ or ‘INSERT’ statements. AFAIK something like that is in planning stage (XQuery Update Facility 1.0). To have this new addition to XQuery in Qt would be great. The question is, what is the better or easier way to do: Implementing a not yet finalized standard, or implementing a feature, which traverses a QDomTree via XQuery, returns one or more QDomNodes, and thus allows to update the underlying QDomTree via the QDom-API.

  17. celso Says:

    Do you have this code in python (pyqt)?

  18. englich Says:

    celso:

    The code in Qt is just a basic C++ Qt API like all other, so whenever bindings are updated to include those APIs, I guess it will include that functionality as well.

  19. charlie Says:

    Just read the news. Thanks very much for your work. I will test out QT-4.5 beta 1 xmlpatterns as soon as possible. Xmlpatterns is the greatest thing to happen in the Linux world for the year 2009 as it represents the pennicle of information technology.

    My only wish is that more web developers know about XSL and have the intelligence and patience to use it. With the added simplicity of XSLT 2 perhaps more developers will be persuaded to use XSL someday.


Leave a reply to englich Cancel reply