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——更简洁的替代方案。

标签:XML