XML,或称为可扩展标记语言(Extensible Markup Language),是一种您可以用来创建自己的标记的标记语言。它由万维网协会(W3C)创建,用来克服 HTML(即超文本标记语言(Hypertext Markup Language),它是所有网页的基础)的局限。和 HTML 一样,XML 基于 SGML — 标准通用标记语言(Standard Generalized Markup Language)。尽管 SGML 已在出版业使用了数十年,但其理解方面的复杂性使许多本打算使用它的人望而却步(SGML 也代表“听起来很棒,但或许以后会用(Sounds great, maybe later)”)。XML 是为 Web 设计的。
XML 文档必须包含在一个单一元素中。这个单一元素称为根元素,它包含文档中所有文本和所有其它元素。在下面的示例中,XML 文档包含在一个单一元素 <greeting>
中。请注意文档有一行注释在根元素之外;那是完全合乎规则的。
下面是一个不包含单一根元素的文档:
<?xml version="1.0"?>
<!-- An invalid document -->
<greeting>
Hello, World!
</greeting>
<greeting>
Hola, el Mundo!
</greeting>
不管该文档可能包含什么信息,XML 解析器都会拒绝它。
XML 元素不能重叠。
结束标记是必需的不能省去任何结束标记。在下面第一个示例中,标记是不合乎规则的,因为没有结束段落(</p>
)标记。尽管这在 HTML(以及某些情况下在 SGML)中可以接受,但 XML 解析器将拒绝它。
<!-- NOT legal XML markup -->
<p>Yada yada yada...
<p>Yada yada yada...
<p>...
如果一个元素根本不包含标记,则称为空元素;HTML 换行(<br>
)和图像(<img>
)元素就是两个例子。在 XML 文档的空元素中,您可以把结束斜杠放在开始标记中。下面的两个换行元素和两个图像元素对于 XML 解析器来说是一回事:
<!-- Two equivalent break elements -->
<br></br>
<br />
<!-- Two equivalent image elements -->
<img src="../img/c.gif"></img>
<img src="../img/c.gif" />
XML 元素是区分大小写的。在 HTML 中,<h1>
和 <H1>
是相同的;在 XML 中,它们是不同的。
如果您试图用 </H1>
标记结束 <h1>
元素,将会出错。
XML 文档中的属性有两个规则:
- 属性必须有值
- 那些值必须用引号括起。
比较下面的两个示例。顶部的标记在 HTML 中是合乎规则的,但在 XML 中则不是。为了在 XML 中取得相同结果,
您必须给属性赋值,而且必须把值括在引号中。
<!-- NOT legal XML markup -->
<ol compact>
<!-- legal XML markup -->
<ol compact="yes">
您可以使用单引号,也可以使用双引号,但要始终保持一致。如果属性值包含单引号或双引号,则您可以使用另一种引号来括起该值(如
name="Doug's car"
),或使用实体
"
代表双引号,使用
'
代表单引号。
实体是一个符号(如
"
),XML 解析器会用其它文本代替该符号(如
"
)。
大多数 XML 文档以 XML 声明作为开始,它向解析器提供了关于文档的基本信息。建议使用 XML 声明,但它不是必需的。如果有的话,那么它
一定是文档的第一样东西。声明最多可以包含三个名称-值对(许多人称它们为属性,尽管在技术上它们并不是)。
version
是使用的 XML 版本;目前该值必须是1.0
。encoding
是该文档所使用的字符集。该声明中引用的ISO-8859-1
字符集包括大多数西欧语言用到的所有字符。如没有指定encoding
,
XML 解析器会假定字符在UTF-8
字符集中,这是一个几乎支持世界上所有语言的字符和象形文字的 Unicode 标准。<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
最后,
standalone
(可以是yes
或no
)定义了是否可以在不读取任何其它文件的情况下处理该文档。例如,如果 XML 文档没有引用任何
其它文件,则您可以指定standalone="yes"
。如果 XML 文档引用其它描述该文档可以包含什么的文件(马上会详细介绍这些文件),则
您可以指定standalone="no"
。因为standalone="no"
是缺省的,所以您很少会在 XML 声明中看到standalone
。
您或许会在一个 XML 文档中发现其它几项:
- 注释:注释可以出现在文档的任何位置;它们甚至可以出现在根元素的前面或后面。注释以
<!--
开始,以-->
结束。注释不能在结束部分以外包含双连字符(--
);除此之外,注释可以包含任何内容。最重要的是,注释内的任何标记都被忽略;如果您希望除去 XML 文档的一块较大部分,只需用注释括住那个部分即可。(要恢复这个注释掉的部分,只需除去注释标记即可。)下面是包含注释的标记:
<!-- Here's a PI for Cocoon: -->
<?cocoon-process type="sql"?>
- 处理指令:处理指令是为使用一段特殊代码而设计的标记。在上面的示例中,有一个用于 Cocoon 的处理指令(有时称为 PI),Cocoon 是来自 Apache 软件基金会(Apache Software Foundation)的 XML 处理框架。当 Cocoon 处理 XML 文档时,它会寻找以
cocoon-process
开头的处理指令,然后相应地处理 XML 文档。在该示例中,type="sql"
属性告诉 Cocoon:XML 文档包含一个 SQL 语句。
<!-- Here's an entity: -->
<!ENTITY dw "developerWorks">
- 实体:上面的示例为文档定义了一个实体。无论 XML 处理器在何处找到字符串
&dw;
,它都会用字符串developerWorks
代替该实体。XML 规范还定义了五个您可以用来替代不同的特殊字符的实体。这些实体是:<
代表小于符号>
代表大于符号"
代表一个双引号'
代表一个单引号(或撇号)&
代表一个“与”符号。
XML 的能力来自它的灵活性,即您和我以及数百万其他人可以定义我们自己的标记来描述我们的数据。记得表示个人姓名和地址的样本 XML 文档吗?那个文档包括表示个人尊称的 <title>
元素,这是对元素名称非常合理的选择。如果您经营一家网上书店,您或许会创建一个表示书名的 <title>
元素。如果您经营一家网上抵押放款公司,您或许会创建表示一份财产名称的 <title>
元素。所有这些都是合理的选择,但它们都用相同的名称创建元素。如何分辨某个特定的 <title>
元素指的是人、书籍还是一份财产呢?可以使用名称空间。
要使用名称空间,您要定义一个名称空间前缀,然后将它映射至一个特殊字符串。下面介绍如何定义我们这三个 <title>
元素的名称空间前缀:
<?xml version="1.0"?>
<customer_summary
xmlns:addr="http://www.xyz.com/addresses/"
xmlns:books="http://www.zyx.com/books/"
xmlns:mortgage="http://www.yyz.com/title/"
>
... <addr:name><title>Mrs.</title> ... </addr:name> ...
... <books:title>Lord of the Rings</books:title> ...
... <mortgage:title>NC2948-388-1983</mortgage:title> ...
在该示例中,三个名称空间前缀是 addr
、books
和 mortgage
。请注意,为特定元素定义名称空间意味着该元素的所有子元素都属于同一名称空间。第一个 <title>
元素属于 addr
名称空间,因为其父元素 <addr:Name>
属于该名称空间。
最后要指出的是:名称空间定义中的字符串仅仅是字符串。对,这些字符串看似 URL,其实不是。您可以定义 xmlns:addr="mike"
,那也是有效的。名称空间唯一的重要性在于其唯一性;这就是为什么大多数名称空间定义看起来象 URL 的原因。XML 解析器不会到 http://www.zyx.com/books/
去搜索 DTD 或模式,它只是把那个文本作为字符串使用。这有些令人困惑,但名称空间就是这样工作的。