XML格式介绍

XML(可扩展标记语言)是一种看起来像HTML,但比HTML更严格、更通用的文档格式。如果说HTML是专门用来描述网页外观的"装修手册",那么XML就是可以描述任何结构化数据的"万能容器"。

XML的由来:从SGML到XML

要理解XML从哪里来,我们先看一个技术家族的简单家谱:

  1. SGML(标准通用标记语言):爷爷辈,1986年诞生,非常强大但也非常复杂

  2. HTML(超文本标记语言):大儿子,1991年诞生,专门用于网页

  3. XML(可扩展标记语言):小儿子,1998年诞生,目标是既保持SGML的结构化能力,又比SGML简单

为什么需要XML?

在90年代,人们遇到了几个问题:

  1. HTML只能描述网页外观,不能描述数据本身的意义

  2. 不同软件之间交换数据很困难,因为没有统一的数据格式

  3. SGML太复杂,不适合在网络上传输

于是,万维网联盟(W3C)在1998年发布了XML 1.0标准。它的设计目标是:

  • 简单易用(相对于SGML)

  • 能在互联网上使用

  • 可扩展(您可以创建自己的标签)

  • 能表示各种类型的数据

一个简单的历史比喻

您可以这样理解这三者的关系:

  • SGML 就像一套完整的乐高积木工厂,可以制造任何形状的积木,但操作复杂

  • HTML 就像一套已经拼好的乐高城堡套装,您只能按说明书拼,不能自己设计

  • XML 则像一盒基础乐高积木,您可以自由组合,创造出任何您想要的东西

XML基础语法:给数据穿上"标签外套"

XML的基本思想很简单:用标签把数据包裹起来,并用这些标签说明数据是什么

标签:XML的基本单位

标签总是成对出现:一个开始标签,一个结束标签。

基本格式:

<标签名>数据内容</标签名>

举例:

<书名>三体</书名>
<价格>45.00</价格>
<作者>刘慈欣</作者>

这里,<书名></书名> 之间的"三体"就是书名数据。

元素:完整的标签包裹内容

一个元素 = 开始标签 + 内容 + 结束标签

<图书>
    <书名>三体</书名>
    <价格>45.00</价格>
</图书>

上面的 <图书> 元素包含了两个子元素:<书名><价格>

属性:给标签添加额外信息

属性写在开始标签内,提供关于元素的额外信息。

格式:

<标签名 属性名="属性值">内容</标签名>

举例:

<图书 类别="科幻" 语言="中文">
    <书名>三体</书名>
    <价格 货币="人民币">45.00</价格>
</图书>

这里,类别="科幻"<图书> 元素的属性,货币="人民币"<价格> 元素的属性。

XML文档的基本结构

每个XML文档都应该有一个根元素,所有其他元素都在这个根元素内部。

完整的XML文档示例:

<?xml version="1.0" encoding="UTF-8"?>
<书店>
    <图书 类别="科幻">
        <书名>三体</书名>
        <作者>刘慈欣</作者>
        <价格 货币="人民币">45.00</价格>
        <出版年>2008</出版年>
    </图书>

    <图书 类别="文学">
        <书名>活着</书名>
        <作者>余华</作者>
        <价格 货币="人民币">38.00</价格>
        <出版年>1993</出版年>
    </图书>
</书店>

这个文档包含以下部分:

  1. XML声明 (第一行):告诉解析器这是XML文档,版本是1.0,编码是UTF-8

  2. 根元素 <书店>:整个文档只有一个根元素

  3. 子元素 :两个 <图书> 元素,每个包含自己的子元素

  4. 属性类别="科幻"

XML的重要规则

XML有一些严格的语法规则,违反这些规则会导致文档无法被解析:

  1. 必须有根元素 :所有元素必须包含在一个根元素内

  2. 标签必须正确嵌套 :后开的标签必须先关闭

    • 正确:<a><b></b></a>

    • 错误:<a><b></a></b>

  3. 标签必须闭合 :每个开始标签必须有对应的结束标签

    • 正确:<书名>三体</书名>

    • 错误:<书名>三体

  4. 大小写敏感<Book><book> 是不同的标签

  5. 属性值必须加引号``类别="科幻"``(双引号或单引号都可以)

  6. 特殊字符需要转义

    • < 要写成 &lt;

    • > 要写成 &gt;

    • & 要写成 &amp;

    • " 要写成 &quot;

    • ' 要写成 &apos;

XML的约束:确保数据格式正确

XML本身只关心语法是否正确,但不关心数据内容是否合理。比如,一个价格标签里写"免费"而不是数字,XML也不会报错。为了解决这个问题,XML提供了两种"约束"机制,用于定义XML文档的结构和规则。

DTD(文档类型定义)

DTD是最早的XML约束方式,它定义了一个XML文档中允许出现的元素、属性和它们的结构。

DTD示例:

<!DOCTYPE 书店 [
    <!ELEMENT 书店 (图书+)>
    <!ELEMENT 图书 (书名, 作者+, 价格, 出版年?)>
    <!ATTLIST 图书 类别 CDATA #REQUIRED>
    <!ELEMENT 书名 (#PCDATA)>
    <!ELEMENT 作者 (#PCDATA)>
    <!ELEMENT 价格 (#PCDATA)>
    <!ATTLIST 价格 货币 CDATA #IMPLIED>
    <!ELEMENT 出版年 (#PCDATA)>
]>

DTD中的符号含义:

  • +:出现一次或多次

  • ?:出现零次或一次

  • *:出现零次或多次

  • #PCDATA:文本内容

  • #REQUIRED:必需的属性

  • #IMPLIED:可选的属性

DTD的优缺点:

  • 优点:简单、紧凑

  • 缺点:功能有限,不支持数据类型(所有内容都是文本),语法与XML不同

XML Schema(XML模式)

XML Schema是更强大的约束语言,它本身也是用XML写的,支持丰富的数据类型。

XML Schema示例(简化):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="书店">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="图书" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="书名" type="xs:string"/>
                            <xs:element name="作者" type="xs:string" maxOccurs="unbounded"/>
                            <xs:element name="价格">
                                <xs:complexType>
                                    <xs:simpleContent>
                                        <xs:extension base="xs:decimal">
                                            <xs:attribute name="货币" type="xs:string" use="optional"/>
                                        </xs:extension>
                                    </xs:simpleContent>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="出版年" type="xs:integer" minOccurs="0"/>
                        </xs:sequence>
                        <xs:attribute name="类别" type="xs:string" use="required"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

XML Schema的特点:

  1. 支持丰富的数据类型(字符串、整数、小数、日期等)

  2. 支持数字范围限制、正则表达式等

  3. 使用XML语法,与文档本身一致

  4. 功能强大但更复杂

简单比喻:

  • DTD 就像一份简单的物品清单:"书架:书若干本;书:书名、作者、价格"

  • XML Schema 就像一份详细的物品规格书:"书架:可放1-100本书;书:书名(1-100字符)、作者(至少1个,最多5个)、价格(0.01-9999.99元,可选货币单位)"

XPath表达式:在XML文档中"导航"

XPath是一种在XML文档中查找信息的语言。您可以把它想象成XML文档的"导航系统"或"查询语言"。

XPath的基本概念

假设我们有以下XML文档:

<书店>
    <图书 类别="科幻">
        <书名>三体</书名>
        <价格>45.00</价格>
    </图书>
    <图书 类别="文学">
        <书名>活着</书名>
        <价格>38.00</价格>
    </图书>
</书店>

常见的XPath表达式

  1. 选择所有书名

    /书店/图书/书名
    

    结果:两个``<书名>``元素("三体"和"活着")

  2. 选择科幻类图书的价格

    /书店/图书[@类别='科幻']/价格
    

    结果:45.00

  3. 选择价格大于40的图书

    /书店/图书[价格 > 40]/书名
    

    结果:"三体"

  4. 选择第一个图书元素

    /书店/图书[1]
    

    结果:第一个``<图书>``元素

  5. 选择所有文本内容

    //书名/text()
    

    结果:"三体"和"活着"

XPath的常用语法

XPath常用语法

表达式

说明

示例

节点名

选择所有名为'节点名'的元素

书名 选择所有<书名>元素

/

从根节点开始选择

/书店/图书 从根开始找图书

//

从当前节点开始选择所有后代节点

//书名 选择文档中所有<书名>

.

当前节点

./书名 选择当前节点的子元素<书名>

父节点

../价格 选择父节点下的<价格>元素

@属性名

选择属性

@类别 选择'类别'属性

[位置]

按位置选择

图书[1] 选择第一个<图书>元素

[条件]

按条件选择

图书[价格>40] 选择价格大于40的图书

为什么需要XPath?

XPath让程序能够:

  1. 精确提取数据:从复杂的XML文档中快速找到所需信息

  2. 验证数据:检查文档是否符合特定条件

  3. 转换数据:为XML转换(XSLT)提供数据选择能力

  4. 简化编程:避免编写复杂的XML解析代码

XML的优缺点分析

优点

  1. 自描述性强:标签名通常能反映数据含义,人类容易理解

    <学生>
        <姓名>张三</姓名>
        <年龄>20</年龄>
    </学生>
    
  2. 平台无关性:纯文本格式,任何系统都能处理

  3. 可扩展性:可以创建自己的标签,适应各种应用场景

  4. 结构化程度高:严格的层次结构,适合表示复杂数据

  5. 强大的生态支持:有XML Schema、XPath、XSLT等完整技术体系

  6. 广泛的标准支持:许多行业标准基于XML(如SOAP、SVG、Office Open XML)

缺点

  1. 冗长繁琐:标签占用了大量空间,文件体积大

    <!-- XML表示 -->
    <person><name>John</name><age>30</age></person>
    
    <!-- JSON表示同样的数据 -->
    {"name": "John", "age": 30}
    
  2. 解析复杂:需要专门的解析器,处理速度相对较慢

  3. 学习曲线较陡:完整的XML技术栈(XML、DTD/Schema、XPath、XSLT)比较复杂

  4. 过度设计嫌疑:对于简单数据,XML可能显得"杀鸡用牛刀"

  5. 不够简洁:相比JSON等格式,XML的语法相对冗长

XML vs JSON:何时选择?

XML与JSON选择指南

场景

推荐使用

原因

文档型数据

XML

XML天生适合表示层次复杂的文档结构,如电子书、办公文档

配置文件中需要注释

XML

XML支持注释(<!-- 注释 -->),而JSON标准不支持注释

Web API数据传输

JSON

JSON更轻量,JavaScript原生支持,更适合网络传输

需要严格的数据验证

XML(配合XML Schema)

XML Schema提供了强大的验证能力,如数据类型、范围、格式等

简单数据交换

JSON

JSON语法更简洁,解析更快,文件体积更小

行业标准要求

按标准要求

如SOAP协议要求XML,RESTful API常用JSON;某些行业有XML标准

XML的实际应用场景

尽管JSON现在更流行,但XML仍在许多领域发挥着重要作用:

  1. 文档格式

    • Microsoft Office文件(.docx, .xlsx, .pptx)

    • Adobe PDF的底层格式

    • eBook格式(EPUB)

  2. 配置文件

    • Java项目的pom.xml(Maven)

    • Android应用的AndroidManifest.xml

    • 许多服务器软件的配置文件

  3. Web服务

    • SOAP协议(企业级Web服务)

    • RSS/Atom订阅源

    • 网站地图(sitemap.xml)

  4. 数据交换

    • SVG矢量图形

    • 地理数据(KML,用于Google Earth)

    • 办公文档的OpenDocument格式

  5. 行业标准

    • 医疗:HL7(医疗信息交换)

    • 金融:FIXML(金融信息交换)

    • 出版:DocBook(技术文档)

一个现实世界的例子:RSS订阅

RSS(简易信息聚合)是XML的经典应用之一:

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>新闻网站</title>
        <link>https://example.com</link>
        <description>最新新闻报道</description>
        <item>
            <title>重大科学发现</title>
            <link>https://example.com/news/123</link>
            <description>科学家宣布了一项重大发现...</description>
            <pubDate>Mon, 01 Jan 2024 12:00:00 GMT</pubDate>
        </item>
        <item>
            <title>经济数据发布</title>
            <link>https://example.com/news/124</link>
            <description>最新经济数据显示增长...</description>
            <pubDate>Mon, 01 Jan 2024 10:00:00 GMT</pubDate>
        </item>
    </channel>
</rss>

总结

XML是一种强大的标记语言,它通过给数据加上有意义的标签,使得数据既能让人类读懂,也能被机器处理。尽管现在JSON在很多场景下更受欢迎,但XML凭借其严谨的结构、强大的验证能力和完整的生态系统,在许多专业领域仍然不可替代。

XML的关键要点

  1. XML是关于数据的,不是关于显示的(那是HTML的工作)

  2. XML是可扩展的,您可以定义自己的标签

  3. XML是严格结构化的,有明确的开始和结束

  4. XML需要配合其他技术使用

    • DTD/XML Schema:定义数据结构

    • XPath:在文档中查找数据

    • XSLT:转换XML文档

给初学者的建议

  1. 先理解基本概念:元素、属性、嵌套关系

  2. 从简单例子开始:尝试创建自己的XML文档

  3. 使用合适的工具:XML编辑器(如VS Code、XMLSpy)可以帮助验证语法

  4. 了解应用场景:知道XML在哪里还在被使用

  5. 不要害怕复杂:XML技术栈确实复杂,但大多数应用只需要基础部分

XML可能看起来有些"老派",但它就像数据库中的关系型数据库一样,在需要严格结构、完整验证和行业标准支持的场景下,仍然是可靠的选择。当您下次遇到``.xml``文件时,不妨用文本编辑器打开看看,也许您会发现,它其实比想象中更容易理解。