XML Schema Regex for Phone Numbers and Postal Codes

XML Schema Definition (XSD) enforces lexical constraints on data elements using regular expressions defined within the xs:pattern facet. By applying these patterns to simple types derived from xs:string or xs:token, you can restrict element values to match specific structural rules. This article demonstrates how to construct and apply XML Schema patterns to validate international phone numbers and varied postal code formats accurately.

Mechanism for Enforcing Lexical Patterns

To constrain the lexical space of an element, create an xs:simpleType with an xs:restriction base of xs:string (or xs:token), and define the matching rules using one or more <xs:pattern> elements. In XSD, regular expressions are implicitly anchored, meaning the entire value must match the pattern from start to end without needing explicit ^ or $ anchors.

<xs:simpleType name="CustomPatternType">
    <xs:restriction base="xs:token">
        <xs:pattern value="[A-Z]{2}[0-9]{4}"/>
    </xs:restriction>
</xs:simpleType>

Enforcing International Phone Numbers

International phone numbers vary widely, but standard validation typically follows the ITU-T E.164 standard or allows common human-readable formatting with spaces, dashes, and parentheses.

Strict E.164 Format

The E.164 format requires a leading + followed by a country code and subscriber number, totaling no more than 15 digits.

<xs:simpleType name="E164PhoneNumber">
    <xs:restriction base="xs:token">
        <!-- Requires a leading '+' followed by 1 to 15 digits (first digit 1-9) -->
        <xs:pattern value="\+[1-9][0-9]{1,14}"/>
    </xs:restriction>
</xs:simpleType>

Flexible International Format

If your schema needs to accept human-formatted numbers containing hyphens, spaces, or parentheses:

<xs:simpleType name="FormattedPhoneNumber">
    <xs:restriction base="xs:token">
        <!-- Allows optional '+', digits, spaces, parentheses, and hyphens (7 to 20 chars) -->
        <xs:pattern value="(\+)?[0-9\s\-\(\)]{7,20}"/>
    </xs:restriction>
</xs:simpleType>

Enforcing International Postal Codes

Because postal code formats differ significantly between countries, you can enforce them using a flexible universal pattern or country-specific patterns combined with an xs:union or multi-branch regex.

Universal International Pattern

A general pattern accommodates alphanumeric codes, spaces, and hyphens used in most global postal systems (e.g., US ZIP codes, UK postcodes, Canadian alphanumeric codes).

<xs:simpleType name="InternationalPostalCode">
    <xs:restriction base="xs:token">
        <!-- 3 to 10 characters consisting of uppercase letters, numbers, hyphens, and spaces -->
        <xs:pattern value="[A-Z0-9\s\-]{3,10}"/>
    </xs:restriction>
</xs:simpleType>

Multi-Pattern Country-Specific Validation

When strict validation is required for known formats, you can combine specific patterns into a single regular expression using the alternation operator (|):

<xs:simpleType name="StrictPostalCode">
    <xs:restriction base="xs:token">
        <!-- US: 12345 or 12345-6789 -->
        <!-- UK: e.g., SW1A 1AA -->
        <!-- Canada: e.g., K1A 0B1 -->
        <xs:pattern value="[0-9]{5}(-[0-9]{4})?|[A-Z]{1,2}[0-9][A-Z0-9]?\s?[0-9][A-Z]{2}|[A-Z][0-9][A-Z]\s?[0-9][A-Z][0-9]"/>
    </xs:restriction>
</xs:simpleType>

Alternatively, you can define separate simple types for each country and combine them using <xs:union>:

<xs:simpleType name="USPostalCode">
    <xs:restriction base="xs:token">
        <xs:pattern value="\d{5}(-\d{4})?"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="CAPostalCode">
    <xs:restriction base="xs:token">
        <xs:pattern value="[A-CEGHJ-NPR-TVXY]\d[A-CEGHJ-NPR-TV-Z] \d[A-CEGHJ-NPR-TV-Z]\d"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="PostalCodeUnion">
    <xs:union memberTypes="USPostalCode CAPostalCode"/>
</xs:simpleType>

Implementation Best Practices

  1. Use xs:token Instead of xs:string: Deriving your simple types from xs:token automatically strips leading and trailing whitespace and collapses internal contiguous whitespace, preventing validation failures caused by formatting artifacts.
  2. Avoid Redundant Anchors: Do not include ^ and $ in the value attribute; XSD pattern matching inherently tests the full length of the string.
  3. Account for Character Escaping: Ensure special characters such as hyphens within character classes are properly escaped (\-) or placed at the beginning or end of the bracketed expression.