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.
1. The example about static typing is not perfectly valid. The difference is in allowing implicit cast in the xslt. The cast exists anyway.
ReplyDelete2. 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 ...
ReplyDeleteI 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.