XML 是「标签名自己起」的标记语言:<book>、<price> 都行,不用等标准组织批准。
但语法必须严格——一个标签没闭合,整篇都不认。
上一节讲的是「给浏览器看的标记」。 这一节讲「给程序传数据用的标记」,它和 HTML 长得像,脾气正好相反。
一、标签可以自己发明
HTML 的标签是定死的:<h1>、<p>、<li> 就那么些,你不能发明一个 <价格> 让浏览器认。
XML 反过来:标签名随你起,只要成对、只要嵌套合法。
所以你能写出 <书><书名>图解 HTTP</书名><作者>上野宣</作者></书> 这种东西,而它确实是合法的 XML。
这就是「可扩展」三个字的意思:结构由你来定,语法由规范来定。
规范只管「尖括号怎么配对」,不管「book 里该有什么」。
二、严格在哪
Demo 里那段 XML 有 9 个元素、最大深度 3 层、共 310 字节,解析得干干净净。
把其中一个 </title> 删掉再解析,直接报错:mismatched tag: line 1, column 27。
整篇都不认,没有「尽量猜」这回事。
同样的写法放进 HTML(<p>没闭合<p>第二段),HTML 的解析器照收不误,还乖乖认出了 4 个标签。
这就是两者最根本的分歧:XML 一个错就全篇不认,HTML 尽量猜你想写什么。
为什么 XML 要这么硬?因为它的用户是程序。程序没法「猜」,猜错了就是数据错乱。
宁可整篇拒绝,也不要给出一个半对的结果。
三、属性还是子元素
同一份数据在 XML 里至少有两种装法:<book id="b1"> 把编号放属性里,
或者 <id>b1</id> 放子元素里。规范不告诉你该用哪种。
这是 XML 的灵活,也是它后来被嫌啰嗦的原因——每个项目都要自己定一套约定,然后写文档、
写校验规则(DTD 或 XSD),不然对方根本猜不到你的结构。
Soap、WSDL 那一代企业级接口就是这么堆起来的:功能很全,但一个简单请求能写出几十行 XML。
这套东西今天还在银行和电信的系统里跑着。
四、动手 Demo:解析一段 XML,再故意弄坏它
写一段书目 XML,用 Python 自带的 ElementTree 解析,数元素、数深度、取字段; 然后把一个闭合标签删掉再解析,看它怎么报错。最后用 HTML 解析器吃同样的「坏」写法,对比两者的态度。
root = ET.fromstring(XML_DOC)
books = root.findall(u'book')
for b in books:
print(b.get(u'id'), b.find(u'title').text)
# 少一个闭合标签
ET.fromstring(u'<library><book><title>没闭合</book></library>')
# ParseError: mismatched tag
实跑输出:
--------------------------------------------------------------------
XML:严格的那一套
--------------------------------------------------------------------
编号 书名 作者 年份
b1 图解 HTTP 上野宣 2014
b2 今夜ワカルHTTP 上野宣 2013
根元素 library
元素总数 9 个
最大深度 3 层
book 的个数 2 个
每个 book 的属性 id、lang
整个文档 310 字节
注意 `id` 和 `lang` 放在属性里,`title`、`author` 放在子元素里——
同一份数据在 XML 里有两种装法,规范不告诉你该用哪种,全看约定。
这是 XML 的灵活,也是它后来被嫌啰嗦的原因之一。
一个有标签没闭合的文档 解析直接失败
报错:mismatched tag: line 1, column 27
同样的写法放进 HTML 照解析,认出 4 个标签
它认出的是 html/body/p/p
一句话总结两者:**XML 一个错就全篇不认,HTML 尽量猜你想写什么。**
两个 book 都取出来了,id 从属性拿,title 从子元素拿——同一份数据两种装法并存,解析器都认。
元素总数 9 个、最大深度 3 层、整篇 310 字节。就这么点数据,标签占了一大半。
坏文档报的是 mismatched tag,位置精确到第 1 行第 27 列。
XML 的报错一向这么具体,因为它假定你是程序,需要准确定位。
同样的「坏」写法给 HTML 解析器,它认出 html/body/p/p 四个标签,一句怨言都没有。
这就是「严格」与「容错」的实测对比。
30 秒实验
- 把
id从属性改成子元素,看解析代码要改哪几行。 - 给 XML 加一行
<?xml-stylesheet?>,想想它和 HTML 的<link>有什么相似。 - 想一想:为什么配置文件(比如 Maven 的 pom.xml)今天还在用 XML?
常见误区
- 「XML 就是 HTML 的升级版」——两者用途不同,一个传数据一个写页面。
- 「XML 比 HTML 严格所以更好」——严格适合机器,容错适合人,看用途。
- 「XML 已经过时了」——数据交换上确实被 JSON 顶掉了,但配置和企业接口还在用。
自测三问(点开对答案)
1. XML 的「可扩展」指的是什么? —— 标签名由使用者自己定义,规范只管语法不管结构。 2. XML 和 HTML 对错误的处理有什么不同? —— XML 一个错整篇拒绝,HTML 尽量容错继续解析。 3. 为什么 XML 要这么严格? —— 它的使用者是程序,猜错就是数据错乱,宁可整篇拒绝。XML 最典型的一个用途,就是让程序读「这个站点最近更新了什么」。
- ☐ (本节完,下一节 10.4.2 发布更新信息的RSS/Atom)