XML简介
XML是被设计用来传输和存储数据的,XML很重要,也很容易学习。
什么是XML
XML指可扩展标记语言(eXtensible Markup Language),它是一种很像HTML的标记语言。XML的设计宗旨是传输数据,焦点是数据的内容,而HTML被设计用来显示数据,其焦点是数据的外观。XML是不会做任何事情的,它只是被设计用来结构化、存储以及传输信息。
XML标签没有被预定义,我们需要自行定义标签,因此XML被设计为具有自我描述性,它是W3C的推荐标准。
通过XML我们可以自定义自己的标签,如:
<mail>
<from>tom</from>
<to>lily</to>
<detail>I will go home this weekend!</detail>
</mail>
上面的这些标签就是我们自定义的,这些标签具有自我描述性:包含了发送者和接受者的信息,同时拥有消息详情。
但是,这个XML文档仍然没有做任何事情。它仅仅是包装在XML标签中的纯粹的信息。我们需要编写软件或者程序,才能传送、接收和显示出这个文档。
目前,XML在Web中起到的作用不会亚于一直作为Web基石的HTML。XML是各种应用程序之间进行数据传输的最常用的工具。
XML用途
在真实的世界中,计算机系统和数据使用不兼容的格式来存储数据。XML数据以纯文本格式进行存储,因此提供了一种独立于软件和硬件的数据存储方法。这让创建不同应用程序可以共享的数据变得更加容易。
对开发人员来说,其中一项最费时的挑战一直是在互联网上的不兼容系统之间交换数据,由于可以通过各种不兼容的应用程序来读取XML中的数据,所以以XML交换数据降低了这种复杂性。
XML结构
XML是一种树结构。树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样。比如:
<bookstore>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="web" cover="paperback">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
</bookstore>
XML文档必须包含根元素,该元素是所有其他元素的父元素。XML文档中的元素形成了一棵文档树,这棵树从根部开始,并扩展到树的最底端。
所有的元素都可以有子元素,父、子以及同胞等术语用于描述元素之间的关系。父元素拥有子元素,相同层级上的子元素成为同胞(兄弟或姐妹)。所有的元素都可以有文本内容和属性(类似于HTML中的元素)
XML语法规则
XML声明,如:
<?xml version="1.0" encoding="utf-8"?>
它定义XML的版本(1.0)和所使用的编码(utf-8)字符集。
所有的XML元素都是成对出现的,有一个开始标签,就必须有一个关闭标签。
XML标签对大小写敏感,标签<Letter>与标签<letter>是不同的。
XML文档必须有根元素,标签如果需要嵌套,必须正确嵌套,在内层打开的标签就必须在内层关闭。
XML标签如果需要添加属性,属性值必须加引号。
在XML中编写注释的语法与HTML的语法很相似,都是 <!– This is a comment –>。
在XML中,空格会被保留,不像HTML中,加再多的空格最终都只合并为一个。
特殊符号:
引用 | 符号 | 说明 |
---|---|---|
< | < | 小于 |
> | > | 大于 |
& | & | and符号 |
' | ‘ | 单引号 |
" | “ | 双引号 |
XML命名规则
XML元素必须遵循以下命名规则:
- 名称可以包含字母、数字以及其他的字符
- 名称不能以数字或者标点符号开始
- 名称不能以字母 xml(或者 XML、Xml 等等)开始
- 名称不能包含空格
- 可使用任何名称,没有保留的字词。
DTD
DTD(文档类型定义)的作用是定义XML文档的合法构建模块。拥有正确语法的XML被称为“形式良好”的XML,我们可以通过DTD验证XML是“合法”的 XML。
为什么使用 DTD?
通过DTD,每一个XML文件均可携带一个有关其自身格式的描述,通过DTD,独立的团体可一致地使用某个标准的DTD来交换数据,而应用程序也可使用某个标准的DTD来验证从外部接收到的数据,还可以使用DTD来验证自身的数据。
DTD的目的是定义XML文档的结构。它使用一系列合法的元素来定义文档结构:
DTD元素
声明一个元素
在DTD中,XML元素通过元素声明来进行声明。元素声明使用下面的语法:
<!ELEMENT 元素名称 类别>
或者
<!ELEMENT 元素名称 (元素内容)>
空元素
空元素通过类别关键词EMPTY进行声明:
<!ELEMENT 元素名称 EMPTY>
示例:
<!ELEMENT br EMPTY>
XML例子:
<br />
只有 PCDATA 的元素
只有 PCDATA 的元素通过圆括号中的#PCDATA进行声明:
<!ELEMENT 元素名称 (#PCDATA)>
示例:
<!ELEMENT from (#PCDATA)>
带有任何内容的元素
通过类别关键词ANY声明的元素,可包含任何可解析数据的组合:
<!ELEMENT 元素名称 ANY>
示例:
<!ELEMENT mail ANY>
带有子元素(序列)的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:
<!ELEMENT 元素名称 (子元素名称 1)>
或者
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>
示例:
<!ELEMENT mail (from,to,detail)>
当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。“mail”元素的完整声明是:
<!ELEMENT mail (from,to,detail)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT detail (#PCDATA)>
声明只出现一次的元素
<!ELEMENT 元素名称 (子元素名称)>
示例:
<!ELEMENT mail (message)>
上面的例子声明了:message子元素必须出现一次,并且必须只在“mail”元素中出现一次。
声明最少出现一次的元素
<!ELEMENT 元素名称 (子元素名称+)>
示例:
<!ELEMENT mail (message+)>
上面的例子中的加号声明了:子元素message必须在“mail”元素内出现至少一次。
声明出现零次或多次的元素
<!ELEMENT 元素名称 (子元素名称*)>
示例:
<!ELEMENT mail (message*)>
上面的例子中的星号声明了:子元素message可在“mail”元素内出现零次或多次。
声明出现零次或一次的元素
<!ELEMENT 元素名称 (子元素名称?)>
示例:
<!ELEMENT mail (message?)>
上面的例子中的问号声明了:子元素message可在“mail”元素内出现零次或一次。
声明“非…/即…”类型的内容
示例:
DTD属性
声明属性
属性声明使用下列语法:
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
示例:
<!ATTLIST dog strain CDATA "labrador">
属性类型的选项:
类型 | 描述 |
---|---|
CDATA | 值为字符数据 (character data) |
(en1|en2|..) | 此值是枚举列表中的一个值 |
ID 值为唯一的 | id |
IDREF | 值为另外一个元素的 id |
IDREFS | 值为其他 id 的列表 |
NMTOKEN | 值为合法的 XML 名称 |
NMTOKENS | 值为合法的 XML 名称的列表 |
ENTITY | 值是一个实体 |
ENTITIES | 值是一个实体列表 |
NOTATION | 此值是符号的名称 |
xml: | 值是一个预定义的 XML 值 |
默认值参数可使用下列值:
值 | 解释 |
---|---|
值 | 属性的默认值 |
REQUIRED | 属性值是必需的 |
IMPLIED | 属性不是必需的 |
FIXED value | 属性值是固定的 |
CDATA与PCDATA
XML文档中的所有文本均会被解析器解析,只有CDATA区段中的文本会被解析器忽略。
PCDATA - 被解析的字符数据
当某个 XML 元素被解析时,其标签之间的文本也会被解析,如:
<name><first>Bill</first><last>Gates</last></name>
解析器会把它分解为像这样的子元素:
<name>
<first>Bill</first>
<last>Gates</last>
</name>
CDATA - (未解析)字符数据
CDATA是不应该由XML解析器解析的文本数据。像“<”和“&”字符在XML元素中都是非法的:“<”会产生错误,因为解析器会把该字符解释为新元素的开始;“&”会产生错误,因为解析器会把该字符解释为特殊字符的开始。
某些文本,比如JavaScript代码,包含大量“<”或“&”字符,为了避免错误,可以将脚本代码定义为 CDATA,CDATA部分中的所有内容都会被解析器忽略。
CDATA 部分由 "<![CDATA["
开始,由 "]]>"
结束,如:
<script>
<![CDATA[
function matchwo(a,b)
{
if (a < b && a < 0)
return 1;
else
return 0;
}
]]>
</script>
该示例中,解析器会忽略 CDATA 部分中的所有内容。
注意:
CDATA部分不能包含字符串“]]>”,也不允许嵌套的CDATA部分。
标记CDATA部分结尾的“]]>”不能包含空格或换行。
内部的DOCTYPE声明
假如DTD被包含在XML源文件中,它应当通过下面的语法包装在一个DOCTYPE声明中:
<!DOCTYPE root-element [element-declarations]>
如:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mail[
<!ELEMENT mail (from,to,detail)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT detail (#PCDATA)>
]>
<mail>
<from>tom</from>
<to>lily</to>
<detail>I will go home this weekend!</detail>
</mail>
!DOCTYPE mail 定义此文档是mail类型的文档。
<!ELEMENT mail (from,to,detail)> 定义mail元素有三个子元素:“to、from、detail”
<!ELEMENT from (#PCDATA)> 定义frome元素为”#PCDATA”类型
外部文档声明
假如DTD位于XML源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
<!DOCTYPE root-element SYSTEM "filename">
这是包含DTD的“mail.dtd”文件:
<!ELEMENT mail (from,to,detail)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT detail (#PCDATA)>
XML文件:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mail SYSTEM "mail.dtd">
<mail>
<from>tom</from>
<to>lily</to>
<detail>I will go home this weekend!</detail>
</mail>