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

Reply via email to