1. In XQuery 1.0, functions need to be declared before use. While in XSLT 2.0, functions may be defined anywhere in the stylesheet (provided, that the function body is a child of the element, xsl:stylesheet).
2. In XQuery 1.0, the XML Schema namespace, http://www.w3.org/2001/XMLSchema is not required to be declared for using the prefix, xs:. While in XSLT 2.0 XML Schema namespace needs to be declared, if any reference to the prefix xs: is made in the XSLT stylesheet.
3. XQuery 1.0 has (seems to me) stronger static typing than XSLT 2.0. For e.g., to return a xs:string value from a function in XQuery 1.0, we cannot simply write, $people/person[fname = $fName]/lname/text(). But instead we have to do for example, xs:string($people/person[fname = $fName]/lname/text()).
While in XSLT 2.0, an expression like $people/person[fname = $fName]/lname is able to return a xs:string value (if element 'lname' contains a text only data).
4. Moreover, an XQuery program is not a template based program description (as is a XSLT, stylesheet). The XQuery syntax looks to me, a mix of procedural and declarative syntax.
It's also true that, XSLT and XQuery are both functional in nature. But that's a similarity, between these two languages!
Following are an XQuery 1.0 and XSLT 2.0 examples which illustrate the above points:
Input XML:
<?xml version="1.0" encoding="UTF-8"?> <people> <person> <fname>Mukul</fname> <lname>Gandhi</lname> </person> <person> <fname>Rohit</fname> <lname>Rawat</lname> </person> </people>
XQuery program:
declare namespace my = "http://localhost/functions"; declare function my:getLastName($people as element(), $fName as xs:string) as xs:string { xs:string($people/person[fname = $fName]/lname/text()) }; <person> <fname>Mukul</fname> <lname>{my:getLastName(doc("../Data/test.xml")/people, "Mukul")}</lname> </person>
XSLT 2.0 stylesheet:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="http://localhost/functions" exclude-result-prefixes="xs my"> <xsl:output method="xml" indent="yes" /> <xsl:template match="/"> <person> <fname>Mukul</fname> <lname><xsl:value-of select="my:getLastName(people,'Mukul')" /></lname> </person> </xsl:template> <xsl:function name="my:getLastName" as="xs:string"> <xsl:param name="people" as="element()" /> <xsl:param name="fName" as="xs:string" /> <xsl:sequence select="$people/person[fname = $fName]/lname" /> </xsl:function> </xsl:stylesheet>
Michael Kay shared following observation on xsl-list:
XQuery tends to work better when you want to extract a small amount of information from a large document and ignore the rest. XSLT tends to work better if you want to keep most things the same and make a few small changes. Of course there's a range of tasks between those extremes.
2 comments:
1. The example about static typing is not perfectly valid. The difference is in allowing implicit cast in the xslt. The cast exists anyway.
2. I would point to a drastically difference between "for" construct in xpath 2.0 and the one in the xquery.
I do not understand WG's reasoning here.
3. The other difference is advanded work with regex in xslt 2.0 "xsl:analyze-string".
4. tunnel parameters, the feature you can model in xquery in no way.
5. xsl:result-document to to produce multiple results in xquery.
Thanks for your remarks ...
I think static typing is more about asking the programmer to specify data typing in the code. So I would think that an explicit cast is a stronger static typing feature than implicit cast.
Post a Comment