XML Schema 1.1 Assertions and XPath 2.0 Constraints

This article provides an overview of assertions in XML Schema (XSD) 1.1, focusing on how they use XPath 2.0 expressions to validate co-occurrence constraints. You will learn the purpose of the xs:assert component, how it overcomes the structural limitations of XSD 1.0, and how to write clear conditional rules between dependent XML elements and attributes.

Understanding Assertions in XSD 1.1

XML Schema 1.1 introduced the <xs:assert> element to allow rule-based data validation directly within schema definitions. In earlier versions (XSD 1.0), validation was strictly structural and context-free, meaning the schema could validate data types and individual element hierarchies, but it could not validate relationships between different elements or attributes within the same context.

An assertion applies a logical condition to a complex type. During validation, the processor checks whether the condition evaluates to true. If the condition evaluates to false, the XML document is marked invalid.

The Role of XPath 2.0

Assertions rely on XPath 2.0 as their predicate language. When an assertion is defined on a complex type, the context node for the XPath expression is the element instance being validated.

XPath 2.0 enhances assertion capabilities in several key ways: * Rich Operators and Functions: Supports mathematical comparisons, string manipulation, date-time calculations, and regular expressions. * Quantified Expressions: Enables the use of every ... in ... satisfies and some ... in ... satisfies to validate collections of child elements. * Conditional Logic: Permits if (...) then ... else ... statements directly inside the validation rule.

Solving Co-Occurrence Constraints

A co-occurrence constraint occurs when the presence, absence, or value of one attribute or element depends on the presence, absence, or value of another. Prior to XSD 1.1, developers had to rely on complex <xs:choice> workarounds or external validation languages like Schematron. With XSD 1.1 assertions, these constraints can be defined declaratively.

Common Use Cases

  1. Mutually Dependent Attributes: Ensuring that if attribute A exists, attribute B must also exist.
  2. Value Comparison: Ensuring that a start date occurs before an end date, or a minimum value is less than or equal to a maximum value.
  3. Conditional Requirements: Requiring specific child elements only when an attribute matches a particular value (e.g., requiring a <creditCardNumber> element only when paymentMethod="credit").

Example Implementation

Consider an XML element representing a product discount where the minimum purchase quantity must be lower than the maximum purchase quantity, and a promo code is mandatory only if the discount rate exceeds 20%.

<xs:element name="DiscountRule">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="minQuantity" type="xs:integer"/>
      <xs:element name="maxQuantity" type="xs:integer"/>
      <xs:element name="discountPercent" type="xs:decimal"/>
      <xs:element name="promoCode" type="xs:string" minOccurs="0"/>
    </xs:sequence>
    
    <!-- Rule 1: minQuantity must be less than maxQuantity -->
    <xs:assert test="minQuantity lt maxQuantity"/>
    
    <!-- Rule 2: promoCode is mandatory if discountPercent > 20 -->
    <xs:assert test="if (discountPercent gt 20) then exists(promoCode) else true()"/>
  </xs:complexType>
</xs:element>

In this example, both <xs:assert> elements are evaluated during validation. If an instance document contains a minQuantity of 50 and a maxQuantity of 30, the schema validator immediately rejects the document based on the first assertion.

Summary

Assertions in XML Schema 1.1 bridge the gap between grammar-based structure validation and business-logic validation. By utilizing XPath 2.0 expressions as predicates on complex types, XSD 1.1 allows developers to enforce co-occurrence constraints and complex dependencies natively within standard XML validation workflows.