A schema-aware processor loads an XSD with xsl:import-schema, and node-building instructions accept type or validation="strict | lax | preserve | strip". In Saxon 12 726,956 that is Saxon-EE only: Saxon-HE rejects xsl:import-schema with XTSE1650 xsl:import-schema requires Saxon-EE and a type attribute with XTSE1660 The @type attribute is available only with a schema-aware XSLT processor. Instead, validate as the next step. reprice.xsl is an identity transform (<xsl:mode on-no-match="shallow-copy"/> copies what no template matches) with one template that rewrites price by $pct percent; xmlschema 476 checks the result against XSD 1.1 Types's XSD 1.1:
xslt3 -s:booknest-catalog.xml -xsl:reprice.xsl pct=-110 -o:repriced.xml
~/de-venv/bin/python -c 'import xmlschema as x
e = list(x.XMLSchema11("catalog11.xsd").iter_errors("repriced.xml"))
print(len(e), "errors, first:", e[0].path, e[0].reason)'6 errors, first: /catalog/book[1]/supply/price value has to be greater than Decimal('0')With pct=10 it is valid, and format-number() turns 20.625 into 20.62 (half to even; round() gives 20.63).
Validation
The <xsl:element>, <xsl:attribute>, <xsl:copy>, <xsl:copy-of>, <xsl:document> and <xsl:result-document> instructions (see Constructing Nodes and Basic Flow Control) can all carry type and validation attributes. This makes it possible to perform XSD validation on the generated XML during an XSLT transformation, using <xsl:import-schema> to bring a schema into scope.<?xml version="1.0" encoding="UTF-8"?>
<!-- transactions_transformed.xsd -->
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="rootType">
<xs:sequence>
<xs:element name="elem"/>
<xs:element name="elem"/>
<xs:element name="elem"/>
<xs:element name="elem"/>
<xs:element name="elem"/>
</xs:sequence>
</xs:complexType>
<xs:element name="elem">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:int">
<xs:attribute name="id"
type="xs:NMTOKEN" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:import-schema
schema-location="transactions_transformed.xsd"/>
<xsl:template match="/">
<xsl:element name="root" type="rootType">
<xsl:element name="elem" type="xs:byte">
<xsl:value-of select="50"/>
</xsl:element>
<xsl:element name="elem" validation="strip">
<xsl:value-of select=" 'Hello' "/>
</xsl:element>
<xsl:element name="elem" validation="preserve">
<xsl:value-of select=" 'Hello' "/>
</xsl:element>
<xsl:element name="elem" validation="strict">
<xsl:attribute name="id">E1</xsl:attribute>
<xsl:value-of select="100"/>
</xsl:element>
<xsl:element name="elem" validation="lax">
<xsl:attribute name="id">E2</xsl:attribute>
<xsl:value-of select="200"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?> <root xmlns:xs="http://www.w3.org/2001/XMLSchema"> <elem>50</elem> <elem>Hello</elem> <elem>Hello</elem> <elem id="E1">100</elem> <elem id="E2">200</elem> </root>
- strip: the new node and its contained nodes are typed as xs:untyped if elements, or xs:untypedAtomic if attributes. XSD validation is not invoked.
- preserve: nodes that are copied or contained keep their existing types; nodes with newly constructed content are annotated as xs:anyType (elements) or xs:untypedAtomic (attributes). XSD validation is not invoked.
- strict: XSD validation is invoked. Validation fails if there is no matching top-level element declaration, or if the outcome is 'invalid' or 'notKnown'.
- lax: XSD validation is invoked. Validation fails only if the outcome is 'invalid'.
The book's examples predate XSD 1.1; the current XSD Recommendation (Part 1: Structures and Part 2: Datatypes) is 1.1, which adds features such as assertions and conditional type assignment on top of the 1.0-era constructs shown here.