Project

Profile

Help

Understanding "declare construction" in XQuery and error "Cannot use a schema-validated source document unless the stylesheet is schema-aware" when using "transform" function

Added by Martin Honnen over 5 years ago

In oXygen 20.1 with Saxon 9.8.0.12 EE as the XQuery engine the XQuery code

let $xslt-doc := <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"><xsl:mode on-no-match="shallow-copy"/><xsl:template match="bar"/></xsl:stylesheet>,
    $example-input := <root><foo><bar>bar 1</bar></foo></root>
return transform(map { 'stylesheet-node' : $xslt-doc, 'source-node' : $example-input })?output

I get the error "Cannot use a schema-validated source document unless the stylesheet is schema-aware".

When I run my local installation of the same version of Saxon EE from the command line it does not give that error. Trying to understand it I played with declare construction preserve; in XQuery and that way also my local copy of EE gives that error. So I assumed Saxon XQuery EE in oXygen is configured to have the construction as "preserve", and indeed when I use declare construction skip; instead even Saxon in oXygen runs the query and does no longer give that error.

Now I am wondering what the error message exactly means, is the XSLT processor configuration the transform function uses when run from Saxon EE XQuery code not a schema-aware (EE) version of Saxon?


Replies (2)

RE: Understanding "declare construction" in XQuery and error "Cannot use a schema-validated source document unless the stylesheet is schema-aware" when using "transform" function - Added by Michael Kay over 5 years ago

I think the transformation invoked by fn:transform will be schema-aware only if either (a) the XSLT code uses a construct such as xsl:import-schema that requires schema-awareness, or (b) schema-awareness is explicitly requested using "is-schema-aware":true() in the option parameters.

The reason for this is that (a) we need to know at compile time whether to make the code schema-aware or not (we can't wait until we see the source document), and (b) compiling for schema-awareness unnecessarily (i.e. when the code doesn't take advantage of it) makes things run slower.

Construction mode in XQuery is pretty horrible. The spec says "If construction mode is preserve, the type of a constructed element node is xs:anyType, and all attribute and element nodes copied during node construction retain their original types. If construction mode is strip, the type of a constructed element node is xs:untyped; all element nodes copied during node construction receive the type xs:untyped, and all attribute nodes copied during node construction receive the type xs:untypedAtomic."

By default we set construction mode to "preserve" if the query is schema-aware, and to "strip" otherwise.

If an element in a source document is typed as xs:anyType, then we treat the document as typed, because it could legitimately contain an explicitly typed node somewhere in the tree; and that means we can't process the document unless the XSLT/XPath/XQuery code was compiled to be schema-aware.

So if construction mode is preserve, but you never do any schema validation, you will have a tree where all the nodes are labelled as xs:anyType quite unnecessarily. It behaves almost like an untyped tree, except that the code processing it has to be look at each node carefully just to be sure there isn't any type information. You're basically getting all the costs of schema-awareness and none of the benefits with this option.

RE: Understanding "declare construction" in XQuery and error "Cannot use a schema-validated source document unless the stylesheet is schema-aware" when using "transform" function - Added by Martin Honnen over 5 years ago

Thanks for the thorough explanation, with the change to

transform(map { 'stylesheet-node' : $xslt-doc, 'source-node' : $example-input, 'requested-properties' : map { QName('http://www.w3.org/1999/XSL/Transform', 'is-schema-aware') : true() } })

I can get it to work although I take it from your explanation that I am better off using declare construction strip; and non schema-aware processing unless the XQuery makes any use of schemas.

    (1-2/2)

    Please register to reply