How to Integrate XSD with Schema-Aware XSLT?
Schema-aware XSLT processors enhance document transformation by incorporating XML Schema Definitions (XSD) directly into the XSLT execution environment. Integrating an XSD allows the transformation engine to validate input and output documents, apply strict data typing, match templates based on schema types rather than just node names, and catch structural errors at compile time. This article explains how to import schemas into stylesheets, enforce input and output validation, and leverage schema types within XPath expressions and template rules.
Importing XML
Schemas Using xsl:import-schema
The primary mechanism for introducing an XSD into an XSLT 2.0 or 3.0
schema-aware stylesheet is the xsl:import-schema
declaration. This element is placed at the top level of the stylesheet
as a child of xsl:stylesheet or
xsl:transform.
You can import a schema by declaring its target namespace and specifying the schema location:
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:app="http://example.com/ns/application">
<xsl:import-schema
namespace="http://example.com/ns/application"
schema-location="schemas/application.xsd" />
</xsl:stylesheet>For schemas without a target namespace, omit the
namespace attribute or specify namespace="".
Once imported, all named simple types, complex types, element
declarations, and attribute declarations from the XSD become accessible
throughout the stylesheet.
Validating Input and Output Documents
Schema-aware XSLT allows explicit validation instructions during document loading, node creation, and result-tree serialization.
Validating Source Documents
When loading source documents via functions such as
doc() or collection(), or processing the
primary input document, you can request validation using
processor-specific flags or standard XSLT instructions. When an input
document is validated against an imported schema, every element and
attribute is annotated with its corresponding schema type instead of
defaulting to untyped data (xs:untyped or
xs:untypedAtomic).
Validating Result Documents and Elements
You can validate constructed output trees by adding the
validation or type attribute to result
elements, literal result elements, xsl:element,
xsl:document, or xsl:result-document.
- Strict Validation: Checks the element and all descendants strictly against declarations in the schema.
<xsl:result-document href="output.xml" validation="strict">
<app:order id="1042">
<app:total>249.99</app:total>
</app:order>
</xsl:result-document>- Lax Validation: Validates elements if a declaration exists in the schema; otherwise, skips validation without throwing an error.
- Type-Based Validation: Validates a constructed element directly against a specific schema type.
<xsl:element name="app:discountPrice" type="app:MonetaryAmountType">
<xsl:value-of select="$calculatedDiscount" />
</xsl:element>Pattern Matching on Schema Types
In standard XSLT, template matching relies on node names and
positions. Schema-aware XSLT introduces type-based pattern matching
using the schema-element() and type() sequence
type tests.
<!-- Match any element declared as an 'order' in the imported schema -->
<xsl:template match="schema-element(app:order)">
<xsl:apply-templates />
</xsl:template>
<!-- Match any node whose type is or derives from MonetaryAmountType -->
<xsl:template match="element(*, app:MonetaryAmountType)">
<span class="currency">
<xsl:value-of select="format-number(., '$#,##0.00')" />
</span>
</xsl:template>This capability decouples transformation rules from specific element tag names, enabling rules that automatically handle any element derived from a common base type.
Type Safety in XPath Expressions and Variables
Integrating XSD allows XPath operations to work with native primitive
types (such as xs:date, xs:decimal, and
xs:boolean) directly from validated source trees without
requiring explicit cast operations like
xs:decimal(price).
<xsl:variable name="taxRate" as="xs:decimal" select="0.08" />
<!-- Direct arithmetic on typed node values -->
<xsl:template match="schema-element(app:item)">
<totalWithTax>
<xsl:value-of select="app:price * (1 + $taxRate)" />
</totalWithTax>
</xsl:template>Functions and named templates can also enforce strict parameter and return types:
<xsl:function name="app:is-expired" as="xs:boolean">
<xsl:param name="expiryDate" as="xs:date" />
<xsl:sequence select="$expiryDate < current-date()" />
</xsl:function>Practical Benefits of Schema Integration
- Early Detection of Errors: Type mismatches and invalid node access are detected during transformation compilation or early execution rather than slipping into downstream systems.
- Simplified XPath Logic: Eliminates redundant data type casting and manual structural checks.
- Processor Optimization: Schema-aware processors can optimize query paths, indexing, and internal memory layouts based on cardinality and type constraints declared in the schema.