面向真实工作场景:写合法文档、看懂解析器报错、处理命名空间与编码、选对校验方式,并能在 28APK 上用格式化、JSON 互转与 XPath 立刻验证思路。下文与 W3School XML 教程、菜鸟教程 XML 指南 等公开资料目录互补,更侧重「排错 + 工程落地」。
把下面链接当作「沙箱」:改一段 XML 立刻格式化、压缩或与 JSON 互转,比只看书更快定位问题。
多数「XML 用不了」并不是语法多难,而是编码、不可见字符、转义、根元素、命名空间这几类坑。下表按现象归类,便于对照搜索引擎或日志里的英文报错。
| 现象 / 报错关键词 | 优先检查 | 建议动作 |
|---|---|---|
| 第 1 行 / 第 2 行就语法错误 | UTF-8 BOM、声明前有空白或输出、复制了不可见字符 | 保存为 UTF-8 无 BOM;确认 <?xml ...?> 前无任何字符;用 XML 格式化 看结构是否被意外截断 |
ampersand、entity、与 & 相关 |
文本节点里写了裸 &、未闭合实体 |
改成 & 或改用 <![CDATA[ ... ]]> 包住大段文本 |
multiple root、多个顶层标签 |
拼接接口结果、复制片段时多根 | 外包一层业务根元素;再用格式化工具检查闭合 |
| 校验通过但 XPath 选不到节点 | 默认命名空间未在 XPath 中声明 | 在 XPath 引擎里绑定与文档相同的 xmlns;或学习 local-name() 写法(本站 XPath 工具 可试) |
| SOAP / Spring / Maven 提示「预期元素」 | 子元素顺序、命名空间 URI、Schema 版本不匹配 | 对照官方 XSD 或样例报文;用 DTD/XSD 校验思路看第 4 节 |
实操建议:遇到陌生报错,先把原文粘进 XML 格式化 得到缩进与行号,再对照解析器指出的行;若涉及与 JSON 的互转,用 XML 与 JSON 互转 做最小样例复现。
XML(eXtensible Markup Language,可扩展标记语言)是一种用于存储和传输数据的标记语言。它是由万维网联盟(W3C)在1998年推出的,设计目标是简化SGML(Standard Generalized Markup Language)的复杂性,同时保留其灵活性和强大功能。
XML是一种元标记语言,它定义了一套规则,用于以人类可读和机器可解析的格式对文档进行编码。XML的主要特点包括:
XML的诞生有其特定的历史背景:
随着时间的推移,许多相关技术也发展起来,包括XML Schema、XSLT、XPath和XQuery等,这些技术共同构成了XML技术栈。
尽管近年来JSON等更简洁的数据格式变得流行,XML仍然在许多领域保持重要地位:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="科幻">
<title>三体</title>
<author>刘慈欣</author>
<year>2008</year>
<price>38.00</price>
</book>
<book category="小说">
<title>活着</title>
<author>余华</author>
<year>1993</year>
<price>35.00</price>
</book>
</bookstore>
注意:XML看起来很像HTML,但它们的用途不同。HTML用于显示数据,而XML用于描述和传输数据。XML没有预定义的标签,标签的含义由文档创建者定义。
要正确使用XML,必须理解其基本语法规则。XML有一套严格的语法,不遵循这些规则的文档将被视为无效。
XML文档通常以XML声明开始,指定XML版本和字符编码:
<?xml version="1.0" encoding="UTF-8"?>
这行声明是可选的,但建议始终包含它。它必须位于文档的第一行,前面不能有任何内容(包括空格)。
XML文档由元素组成,每个元素由开始标签、内容和结束标签组成:
<title>三体</title>
元素命名规则:
XML元素可以包含属性,提供有关元素的额外信息:
<book category="科幻">
属性值必须始终使用引号(单引号或双引号)括起来。与元素类似,属性名也必须遵循命名规则。
XML元素可以嵌套,创建层次结构:
<book>
<title>三体</title>
<author>刘慈欣</author>
</book>
正确的嵌套非常重要。以下是错误的嵌套:
<book><title>三体</book></title> <!-- 错误 -->
没有内容的元素称为空元素,可以使用两种方式表示:
<image src="cover.jpg"></image>
<image src="cover.jpg" /> <!-- 简写形式 -->
XML注释使用以下语法:
<!-- 这是一个XML注释 -->
注释不能包含两个连续的连字符(--),也不能以连字符结尾。
某些字符在XML中有特殊含义(如<和>)。要在文本中使用这些字符,必须使用字符实体:
| 字符 | 实体 |
|---|---|
| < | < |
| > | > |
| & | & |
| ' | ' |
| " | " |
<message>在XML中,<book>标签表示一本书。</message>
显示为:"在XML中,<book>标签表示一本书。"
当需要包含大量特殊字符而不想使用实体时,可以使用CDATA部分:
<script>
<![CDATA[
if (x < y && y > z) {
// 代码逻辑
}
]]>
</script>
CDATA部分中的文本不会被XML解析器解析,所有字符都被视为普通字符。
警告:不遵循XML语法规则的文档将被视为无效XML。大多数XML解析器会拒绝处理无效的XML文档,因此严格遵循语法规则非常重要。
XML文档必须具有良好的结构,即遵循特定的组织形式和规则。良好结构的XML文档更易于处理和理解。
每个XML文档必须有且仅有一个根元素,所有其他元素都嵌套在其中。根元素也被称为文档元素。
<?xml version="1.0" encoding="UTF-8"?>
<bookstore> <!-- 根元素 -->
<book>...</book>
<book>...</book>
</bookstore>
XML文档形成树状结构,元素之间存在父子关系:
<library>
<section name="科技">
<book id="1">
<title>人工智能导论</title>
<author>
<first-name>张</first-name>
<last-name>三</last-name>
</author>
</book>
</section>
</library>
在设计XML文档时,经常需要决定信息应该作为元素还是属性。两种方式各有优缺点:
| 使用元素 | 使用属性 |
|---|---|
| 适合存储数据 | 适合存储元数据(关于数据的数据) |
| 可以包含多个值 | 只能有一个值 |
| 可以嵌套 | 不能嵌套 |
| 容易扩展 | 扩展性有限 |
使用元素表示信息:
<book>
<id>1</id>
<title>XML基础</title>
<language>中文</language>
</book>
使用属性表示相同信息:
<book id="1" title="XML基础" language="中文"></book>
最佳实践: 一般来说,核心数据应该使用元素表示,而用于标识或分类的元数据可以使用属性表示。如果数据需要嵌套结构或可能有多个值,始终使用元素。
当使用来自不同来源的XML文档或在一个文档中混合不同类型的内容时,可能会出现元素名称冲突。XML命名空间提供了解决这个问题的方法。
命名空间使用xmlns属性声明,通常指向唯一的URI:
<root xmlns:h="http://www.w3.org/HTML/1998/html4"
xmlns:f="http://www.furniture.org/items">
<h:table> <!-- HTML表格 -->
<h:tr>
<h:td>数据</h:td>
</h:tr>
</h:table>
<f:table> <!-- 家具桌子 -->
<f:name>餐桌</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>
也可以定义默认命名空间,应用于所有没有前缀的元素:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>默认命名空间示例</title>
</head>
<body>
<h1>这里的所有元素都属于默认命名空间</h1>
</body>
</html>
XML处理指令向应用程序提供特殊指令。它们以<?开始,以?>结束:
<?xml version="1.0" encoding="UTF-8"?> <!-- XML声明是最常见的处理指令 -->
<?xml-stylesheet type="text/xsl" href="style.xsl"?> <!-- 应用XSLT样式表 -->
XML文档可以引用文档类型定义(DTD)或XML Schema,用于验证文档:
<!-- 使用DTD -->
<?xml version="1.0"?>
<!DOCTYPE bookstore SYSTEM "bookstore.dtd">
<bookstore>...</bookstore>
<!-- 使用XML Schema -->
<?xml version="1.0"?>
<bookstore xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="bookstore.xsd">
...
</bookstore>
注意: 良好结构的XML文档是指语法正确的文档,而有效的XML文档是指符合DTD或Schema定义的文档。一个XML文档可以是良好结构的,但不一定有效(如果它不符合指定的DTD或Schema)。
良构(well-formed)只要求语法正确;有效(valid)还要求满足你声明的规则集。对接银行、政务、SOAP、Spring 配置等场景时,「能解析」往往不够,还要「能通过 XSD/DTD」。
| 维度 | DTD | XML Schema (XSD) |
|---|---|---|
| 表达能力 | 较弱,类型系统简单 | 强:数值范围、正则、复杂类型、约束丰富 |
| 命名空间 | 支持有限 | 一等公民,适合大型规范 |
| 典型场景 | 遗留系统、简单内部格式 | 企业集成、公开行业报文、现代 WebService |
内部子集或外部 SYSTEM 引用都能约束元素顺序与出现次数。若报「Element xxx not allowed」类错误,多半是子元素顺序或必填子节点缺失,与接口方 XSD 对照最快。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>服务方</to>
<from>调用方</from>
<body>正文</body>
</note>
常见写法是在根元素上挂 xsi:noNamespaceSchemaLocation 或基于 targetNamespace 的导入链。校验失败时,优先看第一个报错:往往是命名空间 URI 写错、元素名大小写不一致、枚举值不在列表内。
肉眼对齐 XSD 很费力,建议先把报文丢进 XML 格式化,再对照行号与元素层级。
主流模型分三类:DOM(整树进内存,适合中小文档)、SAX / StAX(流式,适合大文件或只关心部分路径)、以及各语言封装的Pull 解析器。选型本质是「内存占用 vs 编程复杂度」。
DOMParser、XMLSerializer;注意与 HTML 解析器差异。xml.etree.ElementTree、lxml(功能更全,XPath 体验好)。System.Xml、XDocument。| 日志关键词 | 常见根因 |
|---|---|
not well-formed | 未闭合标签、非法字符、未转义的 & 等 |
premature end of file | 截断、复制不全、网络传输被截断 |
Invalid character | 控制字符、错误编码声明 |
安全提示:解析不可信 XML 时谨防 XXE、实体扩展炸弹(「十亿大笑攻击」)。生产环境应关闭外部实体、限制解析深度与大小。
XPath 用于在树中定位节点,是 XSLT、XQuery 以及大量配置(如 Spring 的某些表达式)的基础。XSLT 把一份 XML 映射成另一份 XML/HTML/文本,适合「报表模板化」「协议报文变形」。
/root/child;再学轴(ancestor、descendant)。//item[@id='1']。可在本站 XPath 工具 中对同一段 XML 反复试表达式,比死记语法更快。
当你需要可版本化的转换规则、与业务代码解耦、或对接方只接受「模板驱动」的映射时,XSLT 仍有优势;若团队以 TypeScript/Java 为主、转换频繁迭代,也可评估代码化方案,但 XML 侧仍建议保留 XSD 作为契约。
返回顶部 ↑更细的命名、性能与拆分策略,见本站姊妹篇:《XML 最佳实践与性能优化》。
返回顶部 ↑pom.xml、仓库元数据。applicationContext.xml、部分遗留 web.xml 片段。AndroidManifest.xml。.docx / .xlsx 等 ZIP 包内大量 XML)。这些场景的共同点是需要契约(XSD/DTD/规范 PDF)+ 可校验实例。把「官方样例 + 你的最小改动」放进 格式化工具 对比 diff,往往比从头手写更稳。
没有银弹:XML 强在「文档 + 校验 + 命名空间生态」;JSON 强在「Web API + 浏览器原生」;YAML 适合人类编辑的配置;Protobuf 适合高性能二进制 RPC。若你在做开放 HTTP API,JSON 往往是默认;若你在对接遗留 SOAP 或强 XSD 行业报文,XML 仍是主角。
更系统的对比与迁移策略:《XML 与 JSON:深度对比与选型》。需要互转时用 XML ⇄ JSON 互转 做 PoC,再决定字段映射与命名空间处理。
返回顶部 ↑说明:外部链接仅作学习索引;业务与合规请以官方规范及对接方 XSD/文档为准。