Hello, I've noticed that MarkLogic is very literal when it comes to the difference between elements and document nodes in a way that surprised me when it came to XSLT. A simple example:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:template match="/"> <document-node /> </xsl:template> <xsl:template match="/*"> <root-element /> </xsl:template> </xsl:stylesheet> When I call this stylesheet using xdmp:xslt-invoke("test.xslt", document("test.xml")) I get the result <document-node />. When I call it using xdmp:xslt-invoke("test.xslt", document("test.xml")/*), I get the result <root-element />. That's fair enough I suppose, since Marklogic is strictly following the type of the node passed to the XSLT. It makes it annoying to incorporate already-existing XSLTs into Marklogic queries, since we will have to be very careful to always pass in a document node to a transform, even when constructing XML on the fly. This is also different than the behavior I'm used to in eXist, which treated any XML passed to its transform:transform() as a document. I like the eXist behavior better, but I can understand thinking otherwise. However, this becomes a more serious problem when trying to incorporate multi-stage transforms. The behavior in Saxon and MarkLogic differs enough so that the transform must take into account the differing engines to get consistent results. For example: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:template match="/" name="root"> <xsl:param name="count" select="1"/> <xsl:param name="document-tree"> <xsl:apply-templates select="/" mode="other"/> </xsl:param> <xsl:message select="if ($document-tree instance of document-node()) then 'document-node()' else 'element()'"/> <xsl:choose> <xsl:when test="$count lt 2"> <xsl:call-template name="root"> <xsl:with-param name="document-tree" select="$document-tree"/> <xsl:with-param name="count" select="$count + 1"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:choose> <xsl:when test="$document-tree instance of document-node()"> <xsl:message>For Saxon (document-node())</xsl:message> <xsl:apply-templates select="$document-tree/node()"/> </xsl:when> <xsl:otherwise> <xsl:message>For MarkLogic (element())</xsl:message> <xsl:apply-templates select="$document-tree"/> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="@*|node()" mode="#all"> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="#current"/> </xsl:copy> </xsl:template> </xsl:stylesheet> This transform should recurse once and return the original XML. The specific test input is unimportant, but I've been using: <root> <child1/> <child2/> </root> When run in Saxon, I get this as my console output: document-node() document-node() For Saxon (document-node()) When I execute it in Marklogic, passing it a document-node, I get in the log: element-node() element-node() For MarkLogic (element()) If I leave out the xsl:when/xsl:otherwise, I either get infinite looping in Saxon or lose the root element in MarkLogic, depending on whether I use $document-tree/node() or $document-tree for the final apply-templates. I'm not confident enough in my XSLT/XPath knowledge to know when behavior is "correct," but it looks to me that the Saxon behavior maintains the type properly. In any case, is this a MarkLogic implementation bug or just a differing interpretation of the spec? Thanks, James _______________________________________________ General mailing list [email protected] http://developer.marklogic.com/mailman/listinfo/general
