Jesper Tverskov, December 22, 2008

XQuery and XSLT compared

XSLT became a standard in 1999 and XQuery in 2007 but they have so much in common that one of the best things about XSLT and XQuery is that knowing one of them and you can also be fluent in the other in a matter of days.

1. Hand in hand: XQuery and XSLT

XQuery and XSLT each have a spec of their own but major parts of the two languages are based on common standards: data model, XML Schema data types, functions and operators, expressions, serialization:

The short version of the story is that XQuery is more for big XML data jobs, for querying native XML databases or XML on top of relational databases, more for SQL like queries returning "views" of data to be part of some other application. Taking XHTML as example, we could say that XQuery is more for just creating the XHTML table where XSLT is more for creating the full XHTML document.

XSLT is optimized for document to document transformation, but as can be seen from my tutorial, Creating XHTML with XQuery, XQuery can do the same, and in many situations even equally good. When it comes to functionality and features both languages can more or less be substituted for one another except that XQuery is second to none for big XML data jobs, and XSLT likewise for hardcore document to document transformations when input is more document oriented than data oriented.

2. Strengths and weaknesses: XQuery and XSLT

  1. If we just need an SQL like view of data, XQuery is normally so much shorter and more elegant that it makes XSLT look so far out that it is not even worth considering. XQuery is faster for huge data jobs, and better to keep simple jobs simple. [1]
  2. In general XQuery is considered easier to learn.

  3. If input is more document oriented than data oriented, XSLT has an advantage being based on templates as a core feature with build in support for fine tuning like the "priority" attribute, tunneling of parameters, xsl:include/import - xsl:apply-import - xsl:next-match. In XQuery we can mimic XSLT templates with recursive functions and it works well in most situations but not when it really gets hot.

  4. The unparsed-text() function is an XSLT function we don't have in XPath/XQuery. In combination with the xsl:analyze-string element in XSLT (we have nothing like that in XQuery), XSLT is great also to transform non-XML text.

  5. In XSLT 2.0 we have the powerful xsl:for-each-group element to make groupings easy. E.g.: I use xsl:for-each-group to generate the TOC of this document. It can also be done with positional grouping techniques in XQuery (as in XSLT 1.0) if the following-sibling axis is supported, but it is many times more difficult.

  6. Functions like format-number() and format-dateTime() are also only available in XSLT. In XQuery we must rely on simple string manipulation or extensions.

  7. In XSLT we also have the very powerful xsl:number element making it easy to do advanced numbering of almost anything in output, and we have xsl:result-document making it easy to serialize to multiple documents.

  8. XSLT has better support for extensions. We can make the same extension functions in XSLT and XQuery but in XSLT we can also have e.g. extension elements like the extremely powerful "script" element making it possible to use supported programming languages from inside XSLT.

  9. Implementation of serialization parameters is more standardized in XSLT. For transformations to a full document, an XQuery will only work in one XQuery processor and can't even be done in some. The corresponding XSLT stylesheet will work in any XSLT processor.

  10. In XQuery 1.0 we don't have a mechanism like the modified identity template in XSLT to transform and update input without having to recreate parts of it by hand. But with an additional standard, XQuery Update Facility 1.0, already supported by XQuery processors, XQuery is closing this gab. Updates are now one liners in XQuery where they more look like Leporello lists in XSLT.

  11. XSLT being XML is an advantage in many use cases. XSLT can be transformed with XSLT and is easy to nest inside other XML documents. Even though XQuery is shorter to write, there is better intelli-sense for XSLT in most XML Editors making it almost as fast, just as fast or even faster to write. [2]

  12. XSLT being more verbose, more "spelt out", than XQuery, can be hard to live with but has several advantages making XSLT more robust. If we have a complex job expressed in XSLT and XQuery it is much easier to modify and debug XSLT. In the article mentioned in the footnote, MK tells us that this is also true when wanting to add new features to the specs, writing extensions, etc.



See: Comparing XSLT and XQuery, 2005, Michael Kay. I have three comments to this very recommendable article:

  1. I don't understand why MK say's XSLT can only output to XML when we all know that XSLT has serialization options for XML, HTML and text, and in XSLT 2.0 also for XHTML.
  2. The article is dated when it comes to XQuery's lack of update facilities. Today we have an additional spec in the making, XQuery Update Facility 1.0, already implemented in XQuery processors.
  3. It is not entirely true that Microsoft has abandoned XSLT 2.0. The decision was later reversed: Microsoft's XML Team's Weblog: XSLT 2.0 (January 2007). The new decision was then almost reversed back again in Microsoft XML Team's WebLog : Chris Lovett Interview (November 2007) saying what amounts to: "We are busy doing LINQ for the time being". In the meantime we can use e.g. Saxon's XSLT 2.0 processor in .Net, see my article: XSLT 2.0 Saxon in ASP.NET.

XQuery is not only not well-formed when it has a prolog. E.g.: XQuery allows quotes inside quotes. In the XQuery "products2xhtml.xquery" above, we have this example: <tr class="{if ($b mod 2 = 0) then "alt1" else "alt2"}">. Also in XQuery we must use "<" instead of &lt; in math expressions. That is, very often we have no simple way of storing XQuery inside an XML document. It is not enough to make up some element for the XQuery: even as mixed content it is often not well-formed.

Updated 2009-11-13