1. 引言
XML Schema(XSD)是定义 XML 文档结构和数据类型的标准语言。在 XML Schema 中,字符串数据类型是最基础、最常用的类型之一。本文将从内置字符串类型、派生类型、约束限制以及实际应用等方面,详细介绍 XML Schema 中的字符串数据类型,并提供丰富的代码实例。
2. 内置字符串类型
XML Schema 提供了多种内置的字符串相关数据类型,它们都派生自xs:string。下表列出了常用的内置字符串类型:
| 类型 | 说明 | 示例 |
|---|---|---|
xs:string | 任意长度的字符串 | Hello World |
xs:normalizedString | 空白符被规范化的字符串 | Hello World |
xs:token | 空白符被压缩的字符串 | Hello World |
xs:language | 语言标识符 | zh-CN |
xs:NMTOKEN | 名称记号 | item-01 |
xs:Name | XML 名称 | elementName |
xs:NCName | 不带命名空间的 XML 名称 | localName |
xs:ID | 唯一标识符 | id-001 |
xs:IDREF | 引用标识符 | id-001 |
3. 基础字符串类型详解
下面通过一个完整的 XSD 示例来演示xs:string、xs:normalizedString和xs:token的区别。
首先定义一个 XSD 文件:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="book"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="publisher" type="xs:normalizedString"/> <xs:element name="isbn" type="xs:token"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>对应的合法 XML 实例:
<?xml version="1.0" encoding="UTF-8"?> <book> <title>XML 入门与实践</title> <publisher> 清华大学出版社 </publisher> <isbn> 978-7-302-12345-6 </isbn> </book>需要注意:xs:string会保留所有空白字符;xs:normalizedString会将换行符、制表符替换为空格,但保留连续空格;xs:token会进一步压缩连续空格并去除首尾空格。
4. 使用 facet 约束字符串
XML Schema 提供了多种约束(facet)来限制字符串的长度和取值。常用的约束包括length、minLength、maxLength、pattern和enumeration。
4.1 长度约束
下面的示例演示如何使用length、minLength和maxLength约束字符串长度:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- 用户名:长度必须为 6 到 20 个字符 --> <xs:element name="username"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="6"/> <xs:maxLength value="20"/> </xs:restriction> </xs:simpleType> </xs:element> <!-- 国家代码:长度必须恰好为 2 个字符 --> <xs:element name="countryCode"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:length value="2"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:schema>4.2 模式约束(pattern)
pattern使用正则表达式来约束字符串的格式。下面的示例演示如何验证邮箱、手机号和邮政编码:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- 邮箱地址 --> <xs:element name="email"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"/> </xs:restriction> </xs:simpleType> </xs:element> <!-- 中国大陆手机号 --> <xs:element name="phone"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="1[3-9][0-9]{9}"/> </xs:restriction> </xs:simpleType> </xs:element> <!-- 邮政编码:6 位数字 --> <xs:element name="zipCode"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[0-9]{6}"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:schema>4.3 枚举约束(enumeration)
enumeration用于限定字符串只能取指定的几个值。下面的示例定义了一个表示性别的类型:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="gender"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="male"/> <xs:enumeration value="female"/> <xs:enumeration value="other"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:schema>5. 自定义字符串类型
在实际项目中,通常会将常用的字符串约束定义为全局简单类型,以便在多个元素中复用。下面的示例定义了一个通用的「非空字符串」类型和一个「URL 类型」:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- 非空字符串:去除首尾空白后长度至少为 1 --> <xs:simpleType name="nonEmptyString"> <xs:restriction base="xs:string"> <xs:minLength value="1"/> <xs:whiteSpace value="collapse"/> </xs:restriction> </xs:simpleType> <!-- URL 类型 --> <xs:simpleType name="urlType"> <xs:restriction base="xs:string"> <xs:pattern value="https?://[a-zA-Z0-9.-]+(\.[a-zA-Z]{2,})+(/[a-zA-Z0-9._~:/?#\[\]@!$&'()*+,;=%-]*)*"/> </xs:restriction> </xs:simpleType> <xs:element name="user"> <xs:complexType> <xs:sequence> <xs:element name="name" type="nonEmptyString"/> <xs:element name="blog" type="urlType"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>6. 字符串类型在复杂类型中的应用
字符串类型不仅可以用于简单元素,还可以作为复杂类型中属性的类型。下面的示例演示了如何在复杂类型中使用字符串类型和属性:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="product"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="description" type="xs:string" minOccurs="0"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> <xs:attribute name="category" type="xs:token"/> </xs:complexType> </xs:element> </xs:schema>对应的 XML 实例:
<?xml version="1.0" encoding="UTF-8"?> <product id="p-001" category="electronics"> <name>无线鼠标</name> <description>2.4G 无线连接,静音按键</description> </product>7. 空白处理(whiteSpace)
whiteSpacefacet 用于控制处理器对空白字符的处理方式,取值包括preserve、replace和collapse。下面的示例演示三种模式的区别:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- preserve:原样保留空白 --> <xs:element name="preserveText"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:whiteSpace value="preserve"/> </xs:restriction> </xs:simpleType> </xs:element> <!-- replace:将制表符、换行符替换为空格 --> <xs:element name="replaceText"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:whiteSpace value="replace"/> </xs:restriction> </xs:simpleType> </xs:element> <!-- collapse:压缩连续空格并去除首尾空格 --> <xs:element name="collapseText"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:whiteSpace value="collapse"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:schema>8. 综合示例:用户注册信息
下面给出一个综合示例,将前面介绍的各种字符串约束组合起来,定义一个用户注册信息的 Schema:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="registration"> <xs:complexType> <xs:sequence> <xs:element name="username"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[a-zA-Z][a-zA-Z0-9_]{5,19}"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="password"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="8"/> <xs:maxLength value="32"/> <xs:pattern value="(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).*"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="email"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="country"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:length value="2"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="bio" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>对应的合法 XML 实例:
<?xml version="1.0" encoding="UTF-8"?> <registration> <username>zhang_san</username> <password>Abc12345</password> <email>zhangsan@example.com</email> <country>CN</country> <bio>专注于 XML 和 Web 技术。</bio> </registration>9. 总结
XML Schema 的字符串数据类型体系非常丰富,从基础的xs:string到各种派生类型,再到通过 facet 实现的自定义约束,能够满足绝大多数文本数据的校验需求。在实际开发中,建议优先使用xs:token处理不需要保留空白的文本,使用pattern校验格式化的字符串(如邮箱、手机号),并使用enumeration限定取值范围。合理运用这些特性,可以显著提升 XML 数据的规范性和可靠性。