0%

验证xml格式

XML 格式验证:DTD 与 XML Schema 详解

XML(可扩展标记语言)的灵活性使其广泛应用于数据交换和存储,但这种灵活性也带来了格式混乱的风险。为确保 XML 文档的结构合法性和数据有效性,需要通过语义约束机制进行验证。目前主流的 XML 验证方式有两种:DTD(文档类型定义)XML Schema(XML 模式)

DTD(Document Type Definition,文档类型定义)

DTD 是最早的 XML 语义约束标准,通过定义元素、属性、实体等规则,规范 XML 文档的结构。它语法简单,易于理解,但功能有限。

DTD 的引入方式

DTD 可以嵌入 XML 文档内部,或作为外部文件引用,主要有三种引入方式:

(1)内部 DTD

DTD 规则直接定义在 XML 文档内部,仅对当前文档有效。

语法格式

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE 根元素 [
<!-- DTD规则定义 -->
]>
<!-- XML文档内容 -->

示例

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to, from, body)> <!-- note元素必须包含to、from、body子元素,顺序固定 -->
<!ELEMENT to (#PCDATA)> <!-- to元素只能包含文本 -->
<!ELEMENT from (#PCDATA)> <!-- from元素只能包含文本 -->
<!ELEMENT body (#PCDATA)> <!-- body元素只能包含文本 -->
]>
<note>
<to>ll</to>
<from>zh</from>
<body>hello</body>
</note>
(2)外部 DTD

DTD 规则存储在独立的.dtd文件中,可被多个 XML 文档共享,便于维护。

语法格式

1
2
3
<?xml version="1.0"?>
<!DOCTYPE 根元素 SYSTEM "外部DTD文件路径">
<!-- XML文档内容 -->

示例

  • note.dtd(外部 DTD 文件):
1
2
3
4
  <!ELEMENT note (to, from, body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT body (#PCDATA)>
  • XML 文档引用:

    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0"?>
    <!DOCTYPE note SYSTEM "note.dtd">
    <note>
    <to>ll</to>
    <from>zh</from>
    <body>hello</body>
    </note>
(3)公用 DTD

由权威机构制定的公共 DTD(如 HTML、SVG 的标准 DTD),通过PUBLIC关键字引入,需指定唯一标识名。

语法格式

1
<!DOCTYPE 根元素 PUBLIC "DTD标识名" "公用DTD地址">

示例(HTML5 的 DTD):

1
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

DTD 的核心语法

(1)元素声明

定义 XML 元素的结构,包括子元素、文本内容等。

基本语法

1
<!ELEMENT 元素名称 元素类型描述>

元素类型描述

  • PCDATA:元素只能包含文本(Parsed Character Data),不能有子元素。

    1
    <!ELEMENT name (#PCDATA)>  <!-- name元素只能是文本 -->
  • 子元素模型:通过符号定义子元素的组成和顺序:

    • ,:子元素必须按顺序出现(如(a, b, c))。
  • |:子元素任选其一(如(a | b | c))。

    • ?:元素可出现 0 次或 1 次(如a?)。
    • *:元素可出现 0 次或多次(如a*)。
    • +:元素可出现 1 次或多次(如a+)。
      示例
    1
    2
    <!-- 简历必须包含名字、性别、年龄;电话/手机选一个;家庭住址可选;兴趣爱好可多个;教育经历至少一个 -->
    <!ELEMENT 简历 (名字, 性别, 年龄, (电话 | 手机), 家庭住址?, 兴趣爱好*, 教育经历+)>
  • EMPTY:元素必须是空元素(无内容)。
1
<!ELEMENT br EMPTY>  <!-- <br/> 是合法的,<br>内容</br> 不合法 -->
  • ANY:元素可包含任意内容(文本或子元素)。

    1
    <!ELEMENT note ANY>  <!-- note元素内容无限制 -->
(2)属性声明

定义元素的属性规则,包括属性名、类型、约束和默认值。

基本语法

1
2
3
4
<!ATTLIST 元素名 
属性名1 属性类型1 约束1 [默认值1]
属性名2 属性类型2 约束2 [默认值2]
>

属性约束类型

  • #REQUIRED:属性必须存在,无默认值。
  • #IMPLIED:属性可选,无默认值。
  • #FIXED:属性值固定为默认值,不可修改。
  • 直接指定默认值:属性可选,未指定时使用默认值。

常用属性类型

  • CDATA:属性值为字符串。

  • (枚举值1 | 枚举值2 | …):属性值只能是枚举中的一个。

    1
    <!ATTLIST file type (txt | csv | json) #REQUIRED>  <!-- type属性只能是txt、csv或json -->
  • ID:属性值为唯一标识符(整个文档中不可重复)。

  • IDREF:属性值引用另一个元素的ID属性。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0"?>
<!DOCTYPE email [
<!ELEMENT email (body)>
<!ATTLIST email
from CDATA #REQUIRED <!-- from属性必须存在,值为字符串 -->
to CDATA #REQUIRED <!-- to属性必须存在 -->
priority (high | low) "low" <!-- priority可选,默认low -->
>
<!ELEMENT body (#PCDATA)>
]>
<email from="zh" to="ll">
<body>hello</body>
</email>

DTD 的优缺点

  • 优点:

    • 语法简单,易于学习和编写。
  • 解析速度快,兼容性好(所有 XML 解析器都支持)。

  • 缺点:

    • 不支持数据类型(如整数、日期),只能通过字符串间接约束。
  • 不支持命名空间(难以处理多个 DTD 的冲突)。
    • 扩展性差,复杂结构约束能力有限。

XML Schema(XML 模式)

XML Schema(简称 XSD)是 W3C 推出的新一代 XML 约束标准,解决了 DTD 的诸多缺陷。它本身是 XML 文档,支持数据类型、命名空间和复杂约束,功能更强大。

XML Schema 的基本结构

示例(定义 note 元素的 Schema):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema" <!-- 引入Schema命名空间,前缀xs -->
targetNamespace="http://example.com/note" <!-- 当前Schema的命名空间 -->
xmlns="http://example.com/note" <!-- 默认命名空间 -->
elementFormDefault="qualified"> <!-- 元素必须用命名空间限定 -->

<!-- 定义note元素,类型为复杂类型(包含子元素) -->
<xs:element name="note">
<xs:complexType>
<xs:sequence> <!-- 子元素按顺序出现 -->
<xs:element name="to" type="xs:string"/> <!-- to元素为字符串类型 -->
<xs:element name="from" type="xs:string"/> <!-- from元素为字符串类型 -->
<xs:element name="body" type="xs:string"/> <!-- body元素为字符串类型 -->
</xs:sequence>
</xs:complexType>
</xs:element>

</xs:schema>

XML Schema 的核心语法

(1)命名空间与引用

XML Schema 通过命名空间(Namespace)避免元素名冲突,XML 文档需声明引用的 Schema。

XML 文档引用 Schema 的示例

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0"?>
<note
xmlns="http://example.com/note" <!-- 默认命名空间,与Schema的targetNamespace一致 -->
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- Schema实例命名空间 -->
xsi:schemaLocation="http://example.com/note note.xsd"> <!-- 绑定命名空间与Schema文件 -->

<to>ll</to>
<from>zh</from>
<body>hello</body>
</note>
(2)数据类型

XML Schema 提供了丰富的数据类型,分为简单类型(无子元素和属性)和复杂类型(可包含子元素或属性)。

简单类型
  • 内建类型:直接使用的预定义类型,如:

    • 字符串:xs:stringxs:normalizedString(替换换行 / 制表符为空格)。
    • 数值:xs:integerxs:decimalxs:float
    • 日期时间:xs:date(如2023-10-01)、xs:dateTime(如2023-10-01T12:00:00)。
    • 布尔值:xs:booleantruefalse)。
  • 自定义简单类型:通过限制、列表或联合内建类型派生。

    示例 1:限制类型(年龄必须在 0-120 之间)

    1
    2
    3
    4
    5
    6
    7
    8
    <xs:simpleType name="ageType">
    <xs:restriction base="xs:integer"> <!-- 基于整数类型限制 -->
    <xs:minInclusive value="0"/> <!-- 最小值0 -->
    <xs:maxInclusive value="120"/> <!-- 最大值120 -->
    </xs:restriction>
    </xs:simpleType>
    <!-- 使用自定义类型 -->
    <xs:element name="age" type="ageType"/>

示例 2:列表类型(多个年龄值)

1
2
3
4
<xs:simpleType name="ageListType">
<xs:list itemType="ageType"/> <!-- 基于ageType的列表 -->
</xs:simpleType>
<xs:element name="ages" type="ageListType"/> <!-- 合法值:"18 25 30" -->

示例 3:联合类型(价格或日期)

1
2
3
4
  <xs:simpleType name="priceOrDateType">
<xs:union memberTypes="xs:decimal xs:date"/> <!-- 可接受小数或日期 -->
</xs:simpleType>
<xs:element name="value" type="priceOrDateType"/> <!-- 合法值:"99.9" 或 "2023-10-01" -->
复杂类型

用于定义包含子元素或属性的元素,通过<xs:complexType>声明。

示例:带属性的复杂类型

1
2
3
4
5
6
7
8
9
10
11
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
</xs:sequence>
<!-- 定义属性 -->
<xs:attribute name="id" type="xs:integer" use="required"/> <!-- 必需属性id -->
<xs:attribute name="category" type="xs:string" default="fiction"/> <!-- 可选属性,默认fiction -->
</xs:complexType>
</xs:element>

合法的 XML 元素

1
2
3
4
<book id="1001">
<title>XML Guide</title>
<author>John</author>
</book>

XML Schema 的优缺点

  • 优点:

    • 支持丰富的数据类型(整数、日期等),约束更精确。
  • 支持命名空间,可组合多个 Schema 文件。

    • 本身是 XML 文档,易于解析和扩展。
    • 支持复杂结构约束(如条件判断、嵌套类型)。
  • 缺点:

    • 语法较复杂,学习成本高。
  • 解析速度较 DTD 慢(因功能更强大)。

DTD 与 XML Schema 的对比

特性 DTD XML Schema
语法 非 XML 格式,自有语法 纯 XML 格式,遵循 XML 语法
数据类型 仅支持字符串等简单类型 支持丰富的内建类型和自定义类型
命名空间支持 不支持 支持,可避免命名冲突
扩展性 好,支持类型派生和组合
约束能力 基础结构约束 复杂结构、数据范围、条件约束等
学习曲线 简单 较复杂
兼容性 所有 XML 解析器支持 需支持 Schema 的解析器

选择建议

  • 简单场景(如小型配置文件):使用 DTD,简洁高效。
  • 复杂场景(如数据交换、强类型约束):使用 XML Schema,功能更全面。

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10