3.4 XSD:第二代质检规程


3.4 XSD:第二代质检规程

XSD(XML Schema Definition,XML Schema)是 W3C 的第二代契约语言:自身就是 XML 文档、内建四十余种数据类型、原生支持命名空间,还能自定义类型与继承。上一节列的 DTD 两大缺口——无类型、无命名空间——在这里全部补齐。本节从零写一份带类型与次数约束的完整契约,并跑通校验。

从 DTD 翻译成 XSD

同一个 book 契约,XSD 写出来是这样:

<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- 契约本身也是 XML:xs 前缀挂上 Schema 命名空间(第4章细讲) --> <xs:element name="inventory"> <xs:complexType> <xs:sequence> <!-- sequence 对应 DTD 的逗号序列:顺序强制 --> <xs:element name="supplier" type="xs:string"/> <xs:element name="book" maxOccurs="unbounded"> <!-- maxOccurs unbounded 对应 DTD 的加号 --> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="stock" type="xs:integer"/> <!-- 类型!DTD 做不到的核心能力 --> <xs:element name="price" type="xs:decimal" minOccurs="0"/> <!-- minOccurs 0 对应 DTD 的问号 --> </xs:sequence> <xs:attribute name="sku" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>

对照关系一眼可读:sequence = 逗号;maxOccurs="unbounded" = +minOccurs="0" = ?use="required" = #REQUIRED。而 type="xs:integer"type="xs:decimal" 是 DTD 完全没有的东西——<stock>四十二</stock> 会被当场拦下。

内建类型家族速览:数值 xs:integerxs:decimalxs:float;时间 xs:datexs:dateTimexs:duration;文本 xs:stringxs:normalizedStringxs:token;标识 xs:IDxs:IDREF(文档内唯一编号与引用,可部分替代外键);布尔 xs:boolean;还有 xs:anyType 兜底。

自定义类型:facet 收口

真实契约不会只用内建类型。库存在业务上必须是 0 到 10000 的整数,SKU 有固定格式——用 simpleType 加 facet(刻面)收口:

<xs:simpleType name="StockCount"> <xs:restriction base="xs:integer"> <xs:minInclusive value="0"/> <xs:maxInclusive value="10000"/> <!-- 限定整数范围:负库存、天文数字都违规 --> </xs:restriction> </xs:simpleType> <xs:simpleType name="SkuType"> <xs:restriction base="xs:string"> <xs:pattern value="[0-9]{13}"/> <!-- 正则刻面:13 位数字(书号) --> </xs:restriction> </xs:simpleType>

常用 facet:pattern(正则)、minInclusive/maxInclusive(数值范围)、lengthminLength/maxLengthenumeration(枚举值)。enumeration 把 DTD 里那个可怜的属性枚举升级成了任意位置的枚举类型。

校验演练与报错解读

文档端关联契约:根元素挂 xsi:noNamespaceSchemaLocation(或用 targetNamespace + schemaLocation,涉及命名空间,第 4 章后再回头看):

<?xml version="1.0" encoding="UTF-8"?> <inventory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="inventory.xsd"> <supplier>华东书源</supplier> <book sku="9787111407010"> <title>算法导论</title> <stock>-5</stock> </book> </inventory>
命令:xmllint --noout --schema inventory.xsd inventory.xml 输出: inventory.xml:6: element stock: Schemas validity error : Element 'stock': '-5' is not a valid value of the atomic type 'StockCount'(若已应用自定义类型) 库存 document fails to validate,退出码非 0

三个观察点:报错指到具体行;给出违规值与违反的类型名;退出码非零让脚本能自动拦截。改回 42 再跑,退出码 0。变式:把 sku 改成 12 位,pattern 刻面拦下;把 price 移到 title 前,sequence 拦下——三种约束各就各位。

DTD 与 XSD 能力对照

DTD 与 XSD 能力对照

⚠️ XSD 的常见坑是"过度约束":把顺序写死成 sequence,对方系统字段顺序一变就违规。数据交换场景若顺序无语义,可用 xs:all 或放宽为 xs:choice 的 maxOccurs 组合,把契约的火力集中在真正要守的条款上。

本节要点回顾

  • XSD 自身是 XML,可被校验、可被现有工具处理;
  • 次数映射:sequence/choice 对应逗号竖线,minOccurs/maxOccurs 对应问号星号加号;
  • 类型是核心增量:内建类型 + facet 刻面(pattern/范围/枚举);
  • 自定义 simpleType/complexType 支撑复用与继承;
  • 别过度约束:契约管关键条款,不替对方排版。

XSD 里反复出现的 xs: 前缀与 URI,正是命名空间的入口——第 4 章贴标车间开工。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U