Re: [xsl] XSLT 3.0 schema awareness vs non schema awareness

Subject: Re: [xsl] XSLT 3.0 schema awareness vs non schema awareness
From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 27 Feb 2019 08:31:43 -0000
Firstly, you need to be aware that just having a schema around doesn't itself
cause the input to be validated. A stylesheet can have multiple inputs
(including temporary tree variables) and the inputs are only validated if you
ask for this. I only mention this because you didn't...

There are two main consequences of schema-awareness. One is that it enables
stronger compile-time type-checking, which gives you better and earlier
diagnostics when you get your code wrong. If you always get your code right
first time, then of course you will get no benefit from this.

For example, if your stylesheet were written:

<xsl:mode typed="true"/>

> <xsl:template match="test">
>        <result>
>           <xsl:variable name="x" select="val"/>
>           <xsl:copy-of select="$x!fn:sum(., 5)"/>
>        </result>
>     </xsl:template>

and if you declared fn:sum() to expect an xs:date argument, then Saxon would
be able to tell you at compile time that the argument to fn:sum() is of the
wrong type: it knows the type of element test (because the mode declared
typed="true") and can therefore work out that the result of atomizing a "val"
child will be an integer, not a date.

The second consequence of schema-awareness is that you are less dependent on
run-time type conversions. For example, if you do distinct-values(test/val),
then "01" and "1" are considered distinct in the untyped case, but are
considered duplicates in the typed (schema-aware) case. There are many
situations (like your example) where untyped values are implicitly converted
to the required type, but there are other cases where explicit type conversion
is needed to get the correct semantics, unless the type is already known from
schema validation.

The article on schema-awareness that I wrote for Stylus Studio was a long time
ago, but it is still pertinent:

http://www.stylusstudio.com/schema-aware.html

Michael Kay
Saxonica

> On 27 Feb 2019, at 06:57, Mukul Gandhi gandhi.mukul@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> Hi all,
>     Please consider following XSLT examples (I'm using the XSLT 3.0
version), and my questions thereafter,
> (in the presented stylesheets, I'm using XPath 3.0's mapping expressions
[using the operator !]. But my question is not about the ! operator)
>
> I'm using Saxon EE 9.9. Saxon EE 9.7 also produces similar results.
>
> Input XML:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <test>
>    <val>5</val>
>    <val>4</val>
>    <val>3</val>
>    <val>0</val>
>    <val>2</val>
>    <val>0</val>
>    <val>1</val>
> </test>
>
> Stylesheet 1:
> (in this stylesheet, I have an embedded schema & I'm performing schema aware
transformation)
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform
<http://www.w3.org/1999/XSL/Transform>"
>                         xmlns:xs="http://www.w3.org/2001/XMLSchema
<http://www.w3.org/2001/XMLSchema>"
>                         xmlns:fn="http://xslt-functions
<http://xslt-functions/>"
>                         exclude-result-prefixes="xs fn"
>                         version="3.0">
>
>     <xsl:output method="xml" indent="yes"/>
>
>     <!-- an XML schema imported into the stylesheet -->
>     <xsl:import-schema>
>        <xs:schema>
>           <xs:element name="test">
>              <xs:complexType>
>                 <xs:sequence>
>                    <xs:element name="val" type="xs:integer"
maxOccurs="unbounded"/>
>                 </xs:sequence>
>              </xs:complexType>
>           </xs:element>
>        </xs:schema>
>     </xsl:import-schema>
>
>     <xsl:template match="/">
>        <result>
>           <xsl:variable name="x" select="test/val"/>
>           <xsl:copy-of select="$x!fn:sum(., 5)"/>
>        </result>
>     </xsl:template>
>
>     <!-- function to add two numbers -->
>     <xsl:function name="fn:sum" as="xs:integer">
>        <xsl:param name="num" as="xs:integer" />
>        <xsl:param name="incr" as="xs:integer" />
>
>        <xsl:sequence select="$num + $incr"/>
>     </xsl:function>
>
> </xsl:stylesheet>
>
> The above stylesheet, when applied to the input XML, produces following
output,
>
> <?xml version="1.0" encoding="UTF-8"?>
> <result>10 9 8 5 7 5 6</result>
>
> Stylesheet 2:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform
<http://www.w3.org/1999/XSL/Transform>"
>                          xmlns:xs="http://www.w3.org/2001/XMLSchema
<http://www.w3.org/2001/XMLSchema>"
>                          xmlns:fn="http://xslt-functions
<http://xslt-functions/>"
>                          exclude-result-prefixes="xs fn"
>                          version="3.0">
>
>     <xsl:output method="xml" indent="yes"/>
>
>     <xsl:template match="/">
>        <result>
>           <xsl:variable name="x" select="test/val" as="xs:integer*"/>
>           <xsl:copy-of select="$x!fn:sum(., 5)"/>
>        </result>
>     </xsl:template>
>
>     <!-- function to add two numbers -->
>     <xsl:function name="fn:sum" as="xs:integer">
>        <xsl:param name="num" as="xs:integer" />
>        <xsl:param name="incr" as="xs:integer" />
>
>        <xsl:sequence select="$num + $incr"/>
>     </xsl:function>
>
> </xsl:stylesheet>
>
> In above stylesheet, I don't use an embedded schema and don't use schema
aware transformation. In the above stylesheet, I add the syntax
as="xs:integer*" to variable declaration <xsl:variable name="x" ...
> The stylesheet above, produces same output as Stylesheet 1 when applied to
the same input XML document.
>
> Stylesheet 3:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform
<http://www.w3.org/1999/XSL/Transform>"
>                          xmlns:xs="http://www.w3.org/2001/XMLSchema
<http://www.w3.org/2001/XMLSchema>"
>                          xmlns:fn="http://xslt-functions
<http://xslt-functions/>"
>                          exclude-result-prefixes="xs fn"
>                          version="3.0">
>
>     <xsl:output method="xml" indent="yes"/>
>
>     <xsl:template match="/">
>        <result>
>           <xsl:variable name="x" select="test/val" />
>           <xsl:copy-of select="$x!fn:sum(., 5)"/>
>        </result>
>     </xsl:template>
>
>     <!-- function to add two numbers -->
>     <xsl:function name="fn:sum" as="xs:integer">
>        <xsl:param name="num" as="xs:integer" />
>        <xsl:param name="incr" as="xs:integer" />
>
>        <xsl:sequence select="$num + $incr"/>
>     </xsl:function>
>
> </xsl:stylesheet>
>
> In the above stylesheet, I don't use as="xs:integer*" on the mentioned
variable. Otherwise, the above stylesheet is same as Stylesheet 2.
> The stylesheet above, produces same output as stylesheets 1 and 2 when
applied to the same input XML document.
>
> That is, all above three stylesheets produce same output with the same input
XML document.
>
> I wish to know the, pros and cons when comparing above three mentioned
stylesheets, in terms of functionality, performance and may be other factors.
I guess, schema aware transformations in general, are more suited when
rigorous static type checking is needed.
>
>
>
>
> --
> Regards,
> Mukul Gandhi
>
> alt address : mukulgandhi@xxxxxxx <mailto:mukulgandhi@xxxxxxx>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/293509> (by
email <>)

Current Thread