XML 验证工具使用
本章定位 :掌握如何验证 XML 的"格式良好"和"有效性"两个层次,学会使用在线验证器、浏览器内置功能以及 DTD/XSD 关联的正确写法,建立"写完就验"的开发习惯。
定义与作用
XML 质量有两个层次:
| 层次 | 术语 | 含义 | 验证方式 |
|---|---|---|---|
| 第一层 | Well-Formed(格式良好) | 符合 XML 语法规则 | 浏览器直接打开即可检测 |
| 第二层 | Valid(有效) | 既格式良好,又符合 DTD/XSD 定义的文档结构 | 需要验证器 + DTD/Schema 文件 |
为什么需要验证?
XML 是"严格"的语言——一个标签未闭合、大小写不匹配,整个 XML 文档就无法被解析。HTML 浏览器可以"尽力渲染"错误的 HTML,但 XML 解析器 不允许任何语法错误 。
图解释 :XML 处理是严格的"两级检查"流程——先检查语法(Well-Formed),再检查结构(Valid)。任何一级失败都意味着无法继续。
语法/结构要点
DTD 关联方式
<!-- 方式1:内部 DTD(声明写在 XML 内部) -->
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to, from, heading, body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>...</note>
<!-- 方式2:外部 DTD(SYSTEM — 本地文件) -->
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>...</note>
<!-- 方式3:外部 DTD(PUBLIC — 公共标识符) -->
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
XSD 关联方式
<?xml version="1.0"?>
<note
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="note.xsd">
<!-- 或者带命名空间 -->
</note>
<!-- 带命名空间的 XSD -->
<project
xmlns="http://www.feixiang.com/project"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.feixiang.com/project project.xsd">
验证方式对比
| 方式 | 支持级别 | 说明 |
|---|---|---|
| 浏览器直接打开 | Well-Formed 检查 | 打开 XML 文件,浏览器自动报语法错误 |
| 在线验证器 | Well-Formed + DTD/XSD 验证 | 粘贴 XML,选择验证模式 |
| XMLSpy / Oxygen | 全功能验证 + 可视化编辑 | IDE 级工具,自动补全和实时验证 |
| 命令行 | 可脚本化 | xmllint --valid file.xml |
完整示例
场景说明
飞翔科技的 小崔 写了一份订单 XML 和对应的 DTD。产品上线前,白歌要求他逐级验证——先确保格式良好,再用 DTD 验证结构正确性。
测试1:格式良好的 XML
order.xml — 语法正确的订单:
<?xml version="1.0" encoding="UTF-8"?>
<order>
<order_id>1001</order_id>
<customer>大翔</customer>
<items>
<item>
<product>工单模块</product>
<quantity>2</quantity>
<price>50000</price>
</item>
<item>
<product>画像引擎</product>
<quantity>1</quantity>
<price>80000</price>
</item>
</items>
<total>130000</total>
</order>
验证结果 :浏览器打开,显示彩色语法高亮树。格式良好。
测试2:格式不正确——标签大小写不匹配
<?xml version="1.0" encoding="UTF-8"?>
<order>
<order_id>1001</Order_id> <!-- 错误:开始是 order_id,结束是 Order_id -->
<customer>大翔</customer>
</order>
浏览器错误信息 :
error on line 3 at column 11: Opening and ending tag mismatch:
order_id line 3 and Order_id
测试3:验证 DTD 结构——有效 vs 无效
order.dtd :
<!ELEMENT order (order_id, customer, items, total)>
<!ELEMENT order_id (#PCDATA)>
<!ELEMENT customer (#PCDATA)>
<!ELEMENT items (item+)>
<!ELEMENT item (product, quantity, price)>
<!ELEMENT product (#PCDATA)>
<!ELEMENT quantity (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT total (#PCDATA)>
关联 DTD 的 order_valid.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE order SYSTEM "order.dtd">
<order>
<order_id>1001</order_id>
<customer>大翔</customer>
<items>
<item>
<product>工单模块</product>
<quantity>2</quantity>
<price>50000</price>
</item>
</items>
<total>130000</total>
</order>
验证结果 :Well-Formed + Valid — 双通过。
测试4:故意制造 DTD 违规
<!-- 错误:items 缺少子元素,DTD 要求 item+(至少一个 item) -->
<order>
<order_id>1002</order_id>
<customer>白歌</customer>
<items></items> <!-- 违规:需要至少一个 item -->
<total>0</total>
</order>
验证器输出 :
Element 'items' has incomplete content. Expected 'item'.
The element 'items' must have at least one child element 'item'.
操作结果
| 测试 | XML 状态 | 验证结果 |
|---|---|---|
| 测试1 | Well-Formed, 无 DTD | 格式良好,可用 |
| 测试2 | 标签不匹配 | 解析失败,显示错误位置 |
| 测试3 | Well-Formed + Valid | 完全通过 |
| 测试4 | Well-Formed 但 Invalid | DTD 违规:items 缺少 item 子元素 |
实战:XML 常见错误速查表
| 错误类型 | 代码 | 后果 |
|---|---|---|
| 标签未闭合 | <name>大翔 | 解析失败 |
| 大小写不一致 | <Name>...<name> | 开始/结束标签不匹配 |
| 属性值无引号 | <book price=59> | 解析失败 |
| 非法字符 | <price>59 & 50</price> | & 必须写成 & |
| 注释中双横线 | <!-- 这是 -- 注释 --> | 注释非法 |
| 多个根元素 | <a/><b/> | 必须有且仅有一个根元素 |
| 属性重复 | <book id="1" id="2"> | 解析失败 |
易错场景
只测 Well-Formed 不测 Valid
很多开发者用浏览器打开 XML 看到没有错误就认为"没问题了"。但这只是 Well-Formed 检查,不保证满足 DTD/XSD 定义的结构。
<!-- 格式良好但不满足 DTD 的合法结构 -->
<!DOCTYPE order SYSTEM "order.dtd">
<order>
<total>100</total> <!-- DTD 要求 order_id 在前面 -->
<order_id>001</order_id>
</order>
XSD 关联写了 schemaLocation 但路径不对
xsi:schemaLocation="http://www.feixiang.com/project project.xsd"
<!-- project.xsd 不在当前目录,验证器找不到 -->
路径是相对于 XML 文件的,确保 XSD 文件在正确的位置。
混淆 DTD 的 SYSTEM 和 PUBLIC
<!-- SYSTEM:本地文件或私有 DTD -->
<!DOCTYPE note SYSTEM "note.dtd">
<!-- PUBLIC:公共 DTD,有公开的注册标识符 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
PUBLIC 后必须跟两个参数:公共标识符和 URI。SYSTEM 只需要一个 URI。
面试考点
| 考点 | 参考答案要点 |
|---|---|
| Well-Formed 和 Valid 有什么区别? | Well-Formed 是语法正确(标签闭合、大小写一致等);Valid 是在格式良好基础上还符合 DTD/XSD 定义的结构 |
| 如何将 DTD 关联到 XML? | <!DOCTYPE root SYSTEM "path/to/file.dtd">(外部)或 <!DOCTYPE root [...]>(内部) |
| 如何将 XSD 关联到 XML? | 根元素加 xmlns:xsi 和 xsi:noNamespaceSchemaLocation(无命名空间)或 xsi:schemaLocation(有命名空间) |
| XML 有错误时浏览器如何反应? | 显示错误信息并停止处理,不会像 HTML 那样"尽力渲染" |