2026年5月27日 10:49
XML Schema 和 DTD 有什么区别?XSD 为什么取代了 DTD?
XML Schema(XSD)和 DTD 都用来定义 XML 文档的结构和约束,但能力差距很大。XSD 是 DTD 的现代替代方案——基于 XML 语法、支持数据类型、支持命名空间、可扩展可继承。DTD 语法简单但功能有限,新项目几乎不再使用。
核心区别
| 特性 | XML Schema (XSD) | DTD |
|---|---|---|
| 语法 | XML 格式,可用 XML 解析器处理 | 自有语法,不是 XML |
| 数据类型 | 丰富内置类型(string、int、date、boolean 等) | 只有字符串,没有类型区分 |
| 命名空间 | 原生支持 | 不支持 |
| 类型继承 | 支持 extension 和 restriction | 不支持 |
| 可重用性 | 支持类型导入和引用 | 难以复用 |
| 约束精度 | 可定义值范围、正则模式、枚举 | 只能定义元素出现次数 |
简单说:XSD 能做的 DTD 做不了(类型约束、命名空间),DTD 能做的 XSD 都能做且做得更好。
XSD 基础结构
XSD 本身是 XML 文档,根元素是 <xs:schema>:
xml<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="book" type="BookType"/> <xs:complexType name="BookType"> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="price" type="xs:decimal"/> <xs:element name="publishDate" type="xs:date"/> </xs:sequence> <xs:attribute name="id" type="xs:string" use="required"/> </xs:complexType> </xs:schema>
complexType 定义包含子元素或属性的复杂类型,simpleType 定义带约束的简单类型。
XSD 的约束能力
XSD 比 DTD 强的地方在于精确约束:
xml<!-- 值范围约束 --> <xs:simpleType name="AgeType"> <xs:restriction base="xs:integer"> <xs:minInclusive value="0"/> <xs:maxInclusive value="120"/> </xs:restriction> </xs:simpleType> <!-- 正则约束 --> <xs:simpleType name="EmailType"> <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:simpleType name="StatusType"> <xs:restriction base="xs:string"> <xs:enumeration value="active"/> <xs:enumeration value="inactive"/> </xs:restriction> </xs:simpleType>
DTD 只能声明元素存在和出现次数,无法约束值的格式和范围。
类型继承和扩展
XSD 支持两种继承方式:
- extension:在基础类型上添加新元素或属性
- restriction:在基础类型上收紧约束
xml<!-- 扩展:在 PersonType 上加 department --> <xs:complexType name="EmployeeType"> <xs:complexContent> <xs:extension base="PersonType"> <xs:sequence> <xs:element name="department" type="xs:string"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType>
这是 DTD 完全做不到的——DTD 没有类型体系,每个元素定义都是独立的。
在 XML 中引用 XSD
xml<book xmlns="http://www.example.com/books" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/books books.xsd"> <title>XML Guide</title> <price>49.99</price> <publishDate>2024-01-15</publishDate> </book>
schemaLocation 属性成对出现:命名空间 URI + XSD 文件路径。解析器会根据 XSD 验证文档内容。
什么时候还在用 DTD?
DTD 在 2025 年基本只剩这些场景:
- 维护遗留系统(改 DTD 风险比替换小)
- HTML5 的 DOCTYPE 声明(严格说是简化版 DTD)
- 简单的配置文件验证(不值得写 XSD 的场景)
新项目用 XSD,没有理由选 DTD。如果嫌 XSD 太啰嗦,可以考虑 RelaxNG——更简洁的替代方案。