XML 语法详细总结
XML语法详细总结
XML(eXtensible Markup Language,可扩展标记语言)是一种用于存储、传输和描述数据的标记语言,核心特性是可扩展、自描述、语法严格、平台与语言无关,聚焦于「数据是什么」,而非HTML的「数据如何展示」。XML的语法规则具有强约束性,不符合规范的文档会被解析器直接拒绝解析。
一、核心基础概念
1. 两个核心合规标准
XML文档的合规性分为两个层级,是所有语法规则的基础:
| 类型 | 核心要求 | 说明 |
|---|---|---|
| 格式良好的XML | 严格遵守XML基础语法规则 | 解析器可正常解析的最低要求,是文档有效的前提 |
| 有效的XML | 格式良好 + 符合自定义约束规范(DTD/XSD) | 满足业务场景的结构、数据类型、字段约束,是工程化使用的标准 |
2. XML与HTML的核心区别
| 特性 | XML | HTML |
|---|---|---|
| 核心用途 | 数据存储、传输、结构描述 | 网页内容渲染、数据可视化展示 |
| 标签规则 | 完全自定义、可无限扩展 | 预定义固定标签,不可随意扩展 |
| 语法严格度 | 强约束,大小写敏感、标签必须闭合、嵌套必须正确 | 宽松容错,大小写不敏感、标签可省略闭合、允许交叉嵌套 |
| 空白处理 | 默认保留元素内的空白字符 | 自动合并多个连续空白为单个空格 |
| 核心目标 | 定义数据的结构与语义 | 控制数据的展示样式 |
二、XML基础语法铁律(格式良好的必备条件)
以下规则必须100%遵守,任何一条违反都会导致XML文档解析失败,是XML语法的核心底线。
-
必须有且仅有一个根元素 整个文档有且只有一个顶级根元素,所有其他元素都必须嵌套在根元素内部,不允许出现多个同级顶级元素。
<!-- 正确:唯一根元素<root> --> <root> <child>内容</child> </root> <!-- 错误:多个顶级根元素 --> <root1>内容1</root1> <root2>内容2</root2> -
所有标签必须闭合 XML没有自闭合的默认规则,所有标签必须显式闭合,分为两种闭合方式:
- 成对闭合:开始标签 + 结束标签,如
<name>张三</name> - 自闭合:无内容的空元素,结尾必须加
/,如<img src="logo.png" />
<!-- 正确 --> <note>测试内容</note> <br /> <!-- 错误:未闭合 --> <note>测试内容 <br> - 成对闭合:开始标签 + 结束标签,如
-
严格大小写敏感 XML的标签名、属性名、前缀均区分大小写,开始标签和结束标签必须完全匹配。
<!-- 正确:大小写完全一致 --> <Note>内容</Note> <!-- 错误:大小写不匹配 --> <note>内容</Note> -
标签必须正确嵌套,不允许交叉 后开启的标签必须先闭合,标签的嵌套层级必须完全匹配,不允许交叉嵌套。
<!-- 正确:层级嵌套正确 --> <b><i>加粗斜体文本</i></b> <!-- 错误:交叉嵌套 --> <b><i>加粗斜体文本</b></i> -
属性值必须用引号包裹 元素的属性值必须用双引号
"或单引号'完整包裹,不允许省略引号;若属性值内包含双引号,可用单引号包裹,反之亦然。<!-- 正确 --> <book id="001" name='XML"入门"教程' /> <!-- 错误:属性值未加引号 --> <book id=001 name=XML教程 /> -
特殊字符必须使用预定义实体转义 XML中5个字符有特殊语法含义,在文本内容、属性值中使用时,必须用对应的预定义实体转义,否则会导致解析错误。
原始字符 含义 预定义实体 必须转义的场景 <小于号/标签开始 <所有文本内容、属性值中 &和号/实体开始 &所有文本内容、属性值中 >大于号/标签结束 >仅在连续出现 ]]>时需要,其余场景可选"双引号 "双引号包裹的属性值内部 '单引号 '单引号包裹的属性值内部 <!-- 正确:特殊字符转义 --> <expression>1 < 2 && 3 > 0</expression> <info content="他说:"你好"" /> <!-- 错误:未转义特殊字符 --> <expression>1 < 2 && 3 > 0</expression> -
禁止非法字符 XML文档只能使用合法的Unicode字符,不允许出现ASCII控制字符(如\0、\b等),也不允许使用不兼容的Unicode非字符。
三、XML核心组件详解
1. XML文档声明
XML文档声明是可选但强烈建议添加的处理指令,用于告诉解析器XML的版本、编码和独立属性,必须放在文档的第一行,前面不能有任何字符(包括空格、换行、注释、BOM头)。
完整语法:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>version:必填,XML规范版本,主流使用1.0,1.1兼容性差,极少使用encoding:可选,文档字符编码,推荐统一使用UTF-8,避免跨平台乱码standalone:可选,声明文档是否依赖外部DTD文件,yes=不依赖,no=依赖,默认no
2. 元素(标签)
元素是XML文档的核心组成单元,是从开始标签到结束标签的全部内容,用于承载数据和定义结构。
元素命名规则
- 只能包含字母、数字、下划线
_、连字符-、句点. - 必须以字母、下划线
_开头(冒号:仅用于命名空间,不建议随意使用) - 禁止以
xml/XML/Xml等开头(W3C保留关键字) - 禁止包含空格、特殊字符(如
@、$、%等) - 严格区分大小写
元素类型
| 类型 | 示例 | 说明 |
|---|---|---|
| 空元素 | <empty /> |
无任何内容的元素,自闭合写法 |
| 纯文本元素 | <name>张三</name> |
仅包含文本内容,无子元素 |
| 子元素嵌套 | <user><name>张三</name></user> |
包含嵌套的子元素,构建层级结构 |
| 混合内容元素 | <desc>文本<b>加粗</b>内容</desc> |
同时包含文本和子元素,仅推荐富文本场景使用 |
3. 属性
属性是写在元素开始标签内的键值对,用于描述元素的元数据(标识、类型、状态、附加信息),而非核心业务数据。
属性核心规则
- 同一元素内不能有多个同名属性,属性名唯一
- 属性名遵循与元素相同的命名规则,大小写敏感
- 属性值必须用引号包裹,特殊字符必须转义
- 属性不能包含子元素,无法构建层级结构
元素与属性的选择原则
- 核心业务数据用元素承载,元数据/标识信息用属性承载
- 有层级关系、需要扩展的内容用元素,单一固定的描述用属性
- 避免过度使用属性,不要把所有数据都塞进属性中,降低可读性和扩展性
<!-- 推荐:核心数据用元素,元数据用属性 -->
<book id="001" category="技术">
<title>XML语法详解</title>
<author>张三</author>
</book>
<!-- 不推荐:过度使用属性,结构不清晰 -->
<book id="001" category="技术" title="XML语法详解" author="张三" />4. 注释
XML注释用于给文档添加说明文本,解析器会完全忽略注释内容,不会进行解析。
语法:
<!-- 这里是注释内容 -->注释核心规则
- 注释不能嵌套,禁止在注释内再写
<!-- --> - 注释内容中不能包含连续的两个连字符
--,避免解析器误判为注释结束 - 注释不能放在标签内部,也不能放在XML文档声明之前
- 注释不能包围标签的开始/结束部分
<!-- 正确 -->
<!-- 图书列表:2026年更新 -->
<booklist>...</booklist>
<!-- 错误 -->
<book <!-- 图书ID --> id="001">内容</book>
<!-- 错误的--注释内容 -->5. CDATA节
CDATA(Character Data,字符数据)节用于告诉XML解析器:该区域内的内容是纯文本,不解析任何XML标签、实体和特殊字符,适合嵌入包含大量特殊字符的内容(如代码、SQL、HTML片段),避免逐个转义的繁琐。
语法:
<![CDATA[
这里的内容不会被XML解析器解析,<>&""''等特殊字符可直接使用
]]>CDATA核心规则
- CDATA必须写在元素的内容区域,不能放在标签内、属性值中
- CDATA不能嵌套,禁止在CDATA内部再写
<![CDATA[ ]]> - CDATA内容中不能包含结束符
]]>,该字符串会被解析器识别为CDATA结束 - CDATA仅能屏蔽XML语法解析,不会改变文本的编码格式
<!-- 正确:嵌入代码片段,无需转义特殊字符 -->
<code>
<![CDATA[
function compare(a, b) {
if (a < b && a > 0) {
return true;
}
}
]]>
</code>6. 实体
实体是XML中用于定义可复用内容的占位符,分为预定义实体(前文已说明)和自定义实体,自定义实体又分为通用实体和参数实体。
通用实体
用于XML文档内容中,通过&实体名;引用,需在DTD中定义。
- 内部通用实体:内容定义在XML文档内部
<!-- DTD中定义 --> <!ENTITY copyright "版权所有 © 2026 技术出版社"> <!-- 文档中引用 --> <footer>©right;</footer> - 外部通用实体:内容来自外部文件,通过URL引用
⚠️ 注意:外部实体是XXE(XML外部实体注入)漏洞的核心来源,生产环境需禁用外部实体解析。
<!-- DTD中定义 --> <!ENTITY bookinfo SYSTEM "https://example.com/bookinfo.xml"> <!-- 文档中引用 --> <book>&bookinfo;</book>
参数实体
仅用于DTD内部,通过%实体名;引用,用于复用DTD定义片段,语法:
<!-- DTD中定义 -->
<!ENTITY % field_type "(#PCDATA)">
<!-- DTD中引用 -->
<!ELEMENT name %field_type;>
<!ELEMENT author %field_type;>7. 处理指令(PI)
处理指令(Processing Instruction)用于给XML解析器/应用程序传递特殊指令,语法格式为<?目标 指令内容?>,XML文档声明是最常见的处理指令。
常见示例:
<!-- 关联XSL样式表,用于XML渲染 -->
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<!-- 传递PHP指令 -->
<?php echo "Hello XML"; ?>四、XML命名空间(XML Namespace)
XML的可扩展性导致不同场景、不同文档中可能出现同名元素(如<table>既可以表示HTML表格,也可以表示家具桌子),命名空间用于解决元素/属性的命名冲突问题,为标签提供唯一的命名标识。
1. 命名空间声明语法
命名空间通过xmlns属性声明,分为前缀命名空间和默认命名空间,命名空间的URI仅作为唯一标识符,无需可访问。
前缀命名空间
给命名空间定义一个短前缀,元素/属性通过前缀:标签名的方式归属到该命名空间。
<!-- 声明两个命名空间,分别定义前缀h和f -->
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="https://example.com/furniture">
<!-- HTML表格,归属h命名空间 -->
<h:table>
<h:tr><h:td>单元格</h:td></h:tr>
</h:table>
<!-- 家具桌子,归属f命名空间 -->
<f:table>
<f:width>120cm</f:width>
<f:height>80cm</f:height>
</f:table>
</root>默认命名空间
通过xmlns="URI"声明,无前缀,该元素及其所有子元素(无单独命名空间声明)默认归属该命名空间,无需添加前缀。
<!-- 声明默认命名空间 -->
<bookstore xmlns="http://example.com/book">
<!-- 子元素默认归属默认命名空间 -->
<book>
<title>XML语法详解</title>
<author>张三</author>
</book>
</bookstore>2. 命名空间作用域
- 命名空间的作用域为声明该属性的元素及其所有子元素
- 子元素可重新声明命名空间,覆盖父元素的同名前缀/默认命名空间
- 前缀必须先声明命名空间,才能在元素/属性中使用,否则解析错误
五、XML约束规范
约束规范用于定义XML文档的合法结构,验证XML文档的有效性,规定元素的层级、数量、数据类型、属性的必填项、默认值等,主流规范为DTD和XML Schema(XSD)。
1. DTD(文档类型定义)
DTD是XML早期的约束规范,用于定义XML文档的结构规则,分为内部DTD和外部DTD。
基础语法
- 内部DTD:直接写在XML文档内,嵌套在DOCTYPE中
<?xml version="1.0" encoding="UTF-8"?> <!-- 内部DTD声明 --> <!DOCTYPE bookstore [ <!ELEMENT bookstore (book+)> <!ELEMENT book (title, author, price)> <!ATTLIST book id ID #REQUIRED> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT price (#PCDATA)> ]> <bookstore> <book id="bk001"> <title>XML语法详解</title> <author>张三</author> <price>49.9</price> </book> </bookstore> - 外部DTD:定义在独立的
.dtd文件中,XML文档通过SYSTEM引用<!-- 外部DTD文件:bookstore.dtd --> <!ELEMENT bookstore (book+)> <!ELEMENT book (title, author, price)> <!ATTLIST book id ID #REQUIRED> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT price (#PCDATA)> <!-- XML文档中引用 --> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE bookstore SYSTEM "bookstore.dtd"> <bookstore>...</bookstore>
DTD核心能力
- 定义元素的名称、内容类型、出现顺序、出现次数
- 定义属性的名称、类型、默认值、是否必填
- 定义通用实体和参数实体
- 定义元素之间的嵌套关系
DTD局限性
- 语法与XML不一致,学习成本高
- 不支持数据类型校验(无法区分数字、日期、字符串)
- 对命名空间支持差
- 扩展性弱,无法自定义复杂约束规则
2. XML Schema(XSD)
XSD是W3C推荐的DTD替代方案,本身就是XML语法,具备更强大的约束能力,是目前工业界主流的XML约束规范。
核心优势
- 原生XML语法,可与XML文档统一解析
- 支持丰富的数据类型(字符串、数字、日期、布尔、枚举等)
- 完美支持XML命名空间
- 支持自定义复杂数据类型、约束规则、继承扩展
- 支持更精细的元素出现次数、格式校验
基础示例
<!-- XSD文件:bookstore.xsd -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/book"
xmlns:bk="http://example.com/book"
elementFormDefault="qualified">
<!-- 定义根元素bookstore -->
<xs:element name="bookstore">
<xs:complexType>
<xs:sequence>
<xs:element name="book" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="author" type="xs:string" />
<xs:element name="price" type="xs:decimal" />
<xs:element name="pubDate" type="xs:date" />
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<!-- XML文档中引用XSD -->
<?xml version="1.0" encoding="UTF-8"?>
<bk:bookstore xmlns:bk="http://example.com/book"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.com/book bookstore.xsd">
<bk:book id="bk001">
<bk:title>XML语法详解</bk:title>
<bk:author>张三</bk:author>
<bk:price>49.9</bk:price>
<bk:pubDate>2026-01-01</bk:pubDate>
</bk:book>
</bk:bookstore>六、常见语法坑与最佳实践
1. 高频语法踩坑点
- XML文档声明前有空格、换行、注释、UTF-8 BOM头,导致解析失败
- 开始标签与结束标签大小写不匹配,或标签未闭合
- 标签交叉嵌套,层级结构混乱
- 属性值未加引号,或特殊字符未转义
- 文档存在多个顶级根元素
- 注释内包含
--,或注释嵌套 - CDATA内包含结束符
]]>,或CDATA嵌套 - 命名空间前缀未声明就直接使用
- 元素/属性名以
xml开头,或包含空格、非法字符
2. 工程化最佳实践
- 始终添加XML文档声明,统一指定
encoding="UTF-8",禁用UTF-8 BOM头 - 语义化命名,元素/属性使用有业务含义的名称,避免无意义缩写
- 合理区分元素与属性,核心数据用元素,元数据用属性,避免属性滥用
- 非必要不使用混合内容,保持结构层级清晰,提升可读性和解析效率
- 跨系统集成时,必须使用命名空间避免元素命名冲突
- 统一格式化缩进,保持文档结构清晰,便于维护
- 生产环境中,禁用XML解析器的外部实体解析功能,防范XXE注入漏洞
- 业务场景中,优先使用XSD作为约束规范,替代老旧的DTD
- 对XML文档先校验「格式良好」,再校验「约束有效性」,提前定位问题
七、完整XML文档示例
以下示例覆盖了本文所有核心语法规则,是一份格式良好、结构规范的XML文档:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- 图书管理系统XML示例,符合XML 1.0规范 -->
<!DOCTYPE bookstore SYSTEM "bookstore.dtd">
<?xml-stylesheet type="text/xsl" href="bookstyle.xsl"?>
<bookstore xmlns:bk="http://example.com/book"
xmlns:pub="http://example.com/publisher"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.com/book bookstore.xsd">
<bk:book id="bk001" category="技术">
<bk:title>XML语法完全详解</bk:title>
<bk:author>张三</bk:author>
<bk:price currency="CNY">49.9</bk:price>
<pub:publisher>技术出版社</pub:publisher>
<pub:pubDate>2026-01-01</pub:pubDate>
<bk:description>
<![CDATA[
本书覆盖XML全语法体系:
1. 基础语法规则与合规标准
2. 核心组件与命名空间用法
3. DTD/XSD约束规范
4. 工程化最佳实践与安全防护
代码示例:if (a < b && a > 0) { return true; }
]]>
</bk:description>
</bk:book>
</bookstore>