XML 元素
本章定位 :元素是 XML 文档的核心构建块。理解元素的四种内容模型、命名规则,以及"元素 vs 属性"的设计选择原则。
定义与作用
XML 元素 是从 开始标签 到 结束标签 之间的所有内容(包含标签本身)。元素是 XML 文档树的 节点 ,它们通过嵌套关系形成文档的层级结构。
元素可以包含四种内容:文本、子元素、混合内容(文本+子元素),或者为空。理解这四种模型的区别,是设计良好 XML 结构的第一步。
核心原理:元素内容模型与树结构
图解释 :四种内容模型最终都映射到 XML 文档树中。树结构使得任意节点都可以通过父子关系追溯到根——这是 XPath 定位和 DOM 编程的基础。
语法/结构要点
元素命名规则
| 规则 | 允许 | 不允许 |
|---|---|---|
| 首字符 | 字母、下划线、冒号 | 数字、标点符号 |
| 后续字符 | 字母、数字、下划线、横线、点号 | 空格 |
| 名称开头 | 无特殊限制 | 不能以 xml(大小写任意组合)开头 |
| 保留字符 | — | 不能包含空格 |
<!-- ✅ 正确 -->
<book_title>、<_name>、<phone-number>、<ns:element>
<!-- ❌ 错误 -->
<123book>、<book title>、<xmlData>、<book+price>
四种元素内容模型
| 类型 | 说明 | 示例 |
|---|---|---|
| 文本内容 | 元素包含纯文本 | <title>Harry Potter</title> |
| 子元素 | 元素包含其他元素(复合元素) | <book><title>...</title></book> |
| 混合内容 | 同时包含文本和子元素 | <p>This is <b>bold</b> text.</p> |
| 空元素 | 不包含任何内容 | <br/> 或 <lineBreak></lineBreak> |
元素 vs 属性:设计选择原则
W3Schools 推荐: 数据用子元素,元数据用属性 。
| 对比维度 | 属性 | 子元素 |
|---|---|---|
| 数据量 | 适合少量简短数据 | 适合大量结构化数据 |
| 扩展性 | 不能包含子结构 | 可以嵌套任意层级 |
| 多值 | 不方便(需拆分/编码) | 自然支持多子元素 |
| 唯一性 | 同一元素中属性名唯一 | 可有多个同名子元素 |
| 可读性 | 大量属性时降低可读性 | 结构清晰 |
完整示例:小崔重构学生信息 XML
场景说明
飞翔科技技术部正在重构学生管理系统的数据模型。实习生 小崔 最初把学生信息全部塞进属性里,架构师 白歌 代码审查时指出这样设计难以扩展。白歌让他用"数据用子元素,元数据用属性"的原则重新设计。
操作前:全属性设计(不推荐)
<!-- ❌ 全部用属性:不可扩展,可读性差 -->
<student id="2024001" name="小崔" age="22"
major="计算机科学" grade="大三"
email="xiaocui@learnto.cn"
phone="13800138000" address="广州天河"/>
当需要添加"多个联系电话"或"获奖记录"时,这种设计会陷入困境。
操作后:元数据用属性,数据用子元素(推荐)
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="2024001" major="计算机科学">
<name>小崔</name>
<age>22</age>
<grade>大三</grade>
<contact>
<email>xiaocui@learnto.cn</email>
<phone type="mobile">13800138000</phone>
<phone type="dorm">020-88888888</phone>
</contact>
<address>
<city>广州</city>
<district>天河</district>
</address>
<awards>
<award year="2025">ACM校赛一等奖</award>
<award year="2024">国家奖学金</award>
</awards>
</student>
</students>
操作结果
重构后的设计优势明显:
- 扩展无痛 :添加多个电话号码、多个获奖记录都很自然
- 结构清晰 :
contact、address、awards三个子模块各司其职 - 可查询 :
//student[awards/award/@year='2025']可以直接定位到2025年获奖的学生 - 属性用于标识 :
id和major作为元数据用属性存放,而实际数据内容用子元素
易错场景
错误一:元素名含空格
<!-- ❌ -->
<student name>小崔</student name>
<!-- ✅ -->
<student_name>小崔</student_name>
错误二:以 xml 开头的元素名
<!-- ❌ xml、XML、Xml 组合都保留 -->
<xmlData>...</xmlData>
<XMLDocument>...</XMLDocument>
<!-- ✅ 换个前缀 -->
<data_xml>...</data_xml>
错误三:空元素写法不一致
两种写法等价,但应该 在项目中统一风格 :
<!-- 两种写法都正确,但不要混用 -->
<br></br> <!-- 完整闭合 -->
<br/> <!-- 自闭合(推荐) -->
面试考点
| 考点 | 参考答案要点 |
|---|---|
| XML 元素有哪几种内容模型? | 四种:文本内容(#PCDATA)、子元素内容(复合元素)、混合内容、空元素。DTD 中分别用不同声明表示 |
| 属性 vs 子元素,如何选择? | 数据用子元素(可扩展、可嵌套),元数据用属性(ID、类型、分类)。属性不能包含子结构,不能有多个同名属性 |
| 为什么元素名不能以 xml 开头? | W3C 规范保留以 xml(任意大小写组合)开头的名称用于未来标准扩展,用户自定义元素名不能与之冲突 |