XML即可扩展标记语言(eXtensible Markup Language)。标记是指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。如何定义这些标记,既可以选择国际通用的标记语言,比如HTML,也可以使用象XML这样由相关人士自由决定的标记语言,这就是语言的可扩展性。XML是从SGML中简化修改出来的。它主要用到的有XML、XSL和XPath等。
什么是 XML?
- XML 指可扩展标记语言(EXtensible Markup Language)。
- XML 是一种很像HTML的标记语言。
- XML 的设计宗旨是传输数据,而不是显示数据。
- XML 标签没有被预定义。您需要自行定义标签。
- XML 被设计为具有自我描述性。
- XML 是 W3C 的推荐标准。
XML 用途
- XML 把数据从 HTML 分离
- XML 简化数据共享
- XML 简化数据传输
- XML 简化平台变更
- XML 使您的数据更有用
- XML 用于创建新的互联网语言
XML 语法规则
XML 的语法规则很简单,且很有逻辑。这些规则很容易学习,也很容易使用
XML 文档必须有根元素
XML 必须包含根元素,它是所有其他元素的父元素,比如以下实例中 root 就是根元素:
1 | <root> |
以下实例中 note 是根元素:
1 |
|
XML 声明
XML 声明文件的可选部分,如果存在需要放在文档的第一行,如下所示:
1 |
以上实例包含 XML 版本(UTF-8 也是 HTML5, CSS, JavaScript, PHP, 和 SQL 的默认编码)。
所有的 XML 元素都必须有一个关闭标签
在 HTML 中,某些元素不必有一个关闭标签:
1 | <p>This is a paragraph. |
在 XML 中,省略关闭标签是非法的。所有元素都必须有关闭标签:
1 | <p>This is a paragraph.</p> |
注释: 从上面的实例中,您也许已经注意到 XML 声明没有关闭标签。这不是错误。声明不是 XML 文档本身的一部分,它没有关闭标签。
XML 标签对大小写敏感
XML 标签对大小写敏感。标签
必须使用相同的大小写来编写打开标签和关闭标签:
1 | <Message>这是错误的</message> |
注释: 打开标签和关闭标签通常被称为开始标签和结束标签。不论您喜欢哪种术语,它们的概念都是相同的。
XML 必须正确嵌套
在 HTML 中,常会看到没有正确嵌套的元素:
1 | <b><i>This text is bold and italic</b></i> |
在 XML 中,所有元素都必须彼此正确地嵌套:
1 | <b><i>This text is bold and italic</i></b> |
在上面的实例中,正确嵌套的意思是:由于 <i>
元素是在 <b>
元素内打开的,那么它必须在 <b>
元素内关闭
XML 属性值必须加引号
与 HTML 类似,XML 元素也可拥有属性(名称/值的对)。
在 XML 中,XML 的属性值必须加引号。
请研究下面的两个 XML 文档。 第一个是错误的,第二个是正确的:
1 | <note date=12/11/2007> |
在第一个文档中的错误是,note 元素中的 date 属性没有加引号。
实体引用
在 XML 中,一些字符拥有特殊的意义。
如果您把字符 “<” 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
这样会产生 XML 错误:
1 | <message>if salary < 1000 then</message> |
为了避免这个错误,请用实体引用来代替 “<” 字符:
1 | <message>if salary < 1000 then</message> |
在 XML 中,有 5 个预定义的实体引用:
< | < | less than |
---|---|---|
> | > | greater than |
——- | — | —- |
& | & | ampersand |
——- | — | —- |
' | ‘ | apostrophe |
——- | — | —- |
" | “ | quotation mark |
注释: 在 XML 中,只有字符 “<” 和 “&” 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。 |
XML 中的注释
1 | <!-- 注释 --> |
在 XML 中,空格会被保留
HTML 会把多个连续的空格字符裁减(合并)为一个:
HTML: | Hello Tove |
---|---|
Output: | Hello Tove |
在 XML 中,文档中的空格不会被删减。 |
XML 以 LF 存储换行
在 Windows 应用程序中,换行通常以一对字符来存储:回车符(CR)和换行符(LF)。
在 Unix 和 Mac OSX 中,使用 LF 来存储新行。
在旧的 Mac 系统中,使用 CR 来存储新行。
XML 以 LF 存储换行。
XML语法
XML文档声明
1 |
- 文档声明必须为
<?xml
开头,以?>
结束 - 文档声明必须从文档的0行0列位置开始,也就是说必须放在顶部位置
- 文档声明只有三个属性:
- version:指定xml文档版本。必须属性,因为我们不会选择1.1,只会选择1.0
- encoding:指定当前文档的编码。可选属性。默认值是utf-8
元素
元素是XML文档中最重要的组成部分
普通元素的结构开始标签、元素体、结束标签组成。例如:
1
<hello>大家好</hello>
元素体:元素体可以是元素,也可以是文本,例如:
1
<hello><world>hello world!</world></hello>
空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合,例如:
<c/>
元素命名
- 区分大小写
- 不能使用空格,不能使用冒号
- 不建议以xml、XML、Xml开头
格式化良好的xml文档,必须只有一个根元素
属性
1 | <web-app version="2.5"> |
- 属性是元素的一部分,他必须出现在元素的开始标签中
- 属性的定义格式:属性名=属性值,其中,属性值必须使用单引/双引
- 一个元素可以有0~N个属性,但一个元素中不能出现同名属性
- 属性名不能使用空格、冒号等特殊字符,且必须以字母开头
PCDATA
PCDATA 的意思是被解析的字符数据(parsed character data)。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 “&”;、”<”; 以及 “>”; 实体来分别替换它们。
CDATA
术语 CDATA 指的是不应由 XML 解析器进行解析的文本数据(Unparsed Character Data)。
在 XML 元素中,”<” 和 “&” 是非法的。
“<” 会产生错误,因为解析器会把该字符解释为新元素的开始。
“&” 也会产生错误,因为解析器会把该字符解释为字符实体的开始。
某些文本,比如 JavaScript 代码,包含大量 “<” 或 “&” 字符。为了避免错误,可以将脚本代码定义为 CDATA。
CDATA 部分中的所有内容都会被解析器忽略。
CDATA 部分由 ““ 结束:
1 | <script> |
在上面的例子中,解析器会忽略 CDATA 部分中的所有内容。
DTD
文档类型定义(Document Type Definition)是一套为了进行程序间的数据交换而建立的关于标记符的语法规则。它是标准通用标记语言和可扩展标记语言1.0版规格的一部分,文档可根据某种DTD语法规则验证格式是否符合此规则。文档类型定义也可用做保证标准通用标记语言、可扩展标记语言文档格式的合法性,可通过比较文档和文档类型定义文件来检查文档是否符合规范,元素和标签使用是否正确。文件实例提供应用程序一个数据交换的格式。使用各类文档类型定义是为了让标准通用标记语言、可扩展标记语言文件能符合规定的数据交换标准,因为这样,不同的公司只需定义好标准文档类型定义,就都能依文档类型定义建立文档实例,并且进行验证,如此就可以轻易交换数据,防止了实例数据定义不同等原因造成的数据交换障碍,满足了网络共享和数据交互。文档类型定义文件是一个美国信息交换标准代码文本文件。
为什么使用DTD文档
- 通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
- 通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。 - 您还可以使用 DTD 来验证您自身的数据。
内部的 DOCTYPE 声明
假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:
1 |
示例:
1 |
|
以上 DTD 解释如下:
- !DOCTYPE note (第二行)定义此文档是 note 类型的文档。
- !ELEMENT note (第三行)定义 note 元素有四个元素:”to、from、heading,、body”
- !ELEMENT to (第四行)定义 to 元素为 “#PCDATA” 类型
- !ELEMENT from (第五行)定义 from 元素为 “#PCDATA” 类型
- !ELEMENT heading (第六行)定义 heading 元素为 “#PCDATA” 类型
- !ELEMENT body (第七行)定义 body 元素为 “#PCDATA” 类型
外部文档声明
假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
1 |
这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD: (点击打开该文件,并选择”查看源代码”命令。)
1 |
|
这是包含 DTD 的 “note.dtd” 文件:
1 | <!ELEMENT note (to,from,heading,body)> |
DTD元素
在一个 DTD 中,元素通过元素声明来进行声明。
声明一个元素
在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法:
1 | <!ELEMENT element-name category> |
或
1 | <!ELEMENT element-name (element-content)> |
空元素
空元素通过类别关键词EMPTY进行声明:
1 | <!ELEMENT element-name EMPTY> |
实例:
1 | <!ELEMENT br EMPTY> |
XML example:
1 | <br /> |
只有 PCDATA 的元素
只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:
1 | <!ELEMENT element-name (#PCDATA)> |
实例:
1 | <!ELEMENT from (#PCDATA)> |
带有任何内容的元素
通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:
1 | <!ELEMENT element-name ANY> |
实例:
1 | <!ELEMENT note ANY> |
带有子元素(序列)的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:
1 | <!ELEMENT element-name (child1)> |
或
1 | <!ELEMENT element-name (child1,child2,...)> |
实例:
1 | <!ELEMENT note (to,from,heading,body)> |
当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。”note” 元素的完整声明是:
1 | <!ELEMENT note (to,from,heading,body)> |
声明只出现一次的元素
1 | <!ELEMENT element-name (child-name)> |
实例:
1 | <!ELEMENT note (message)> |
上面的例子声明了:message 子元素必须出现一次,并且必须只在 “note” 元素中出现一次。
声明最少出现一次的元素(+)
1 | <!ELEMENT element-name (child-name+)> |
实例:
1 | <!ELEMENT note (message+)> |
上面的例子中的加号(+)声明了:message 子元素必须在 “note” 元素内出现至少一次。
声明出现零次或多次的元素(*)
1 | <!ELEMENT element-name (child-name*)> |
实例:
1 | <!ELEMENT note (message*)> |
上面的例子中的星号(*)声明了:子元素 message 可在 “note” 元素内出现零次或多次。
声明出现零次或一次的元素(?)
1 | <!ELEMENT element-name (child-name?)> |
实例:
1 | <!ELEMENT note (message?)> |
上面的例子中的问号(?)声明了:子元素 message 可在 “note” 元素内出现零次或一次。
声明”非…/既…”类型的内容
实例:
1 | <!ELEMENT note (to,from,header,(message|body))> |
上面的例子声明了:”note” 元素必须包含 “to” 元素、”from” 元素、”header” 元素,以及非 “message” 元素既 “body” 元素。
声明混合型的内容
实例:
1 | <!ELEMENT note (#PCDATA|to|from|header|message)*> |
上面的例子声明了:”note” 元素可包含出现零次或多次的 PCDATA、”to”、”from”、”header” 或者 “message”。
DTD - 属性
在 DTD 中,属性通过 ATTLIST 声明来进行声明。
属性声明使用下列语法:
1 | <!ATTLIST element-name attribute-name attribute-type attribute-value> |
DTD 实例:
1 | <!ATTLIST payment type CDATA "check"> |
XML 实例:
1 | <payment type="check" /> |
以下是 属性类型的选项:
类型 | 描述 |
---|---|
CDATA | 值为字符数据 (character data) |
(en1|en2|..) | 此值是枚举列表中的一个值 |
ID | 值为唯一的 id |
IDREF | 值为另外一个元素的 id |
IDREFS | 值为其他 id 的列表 |
NMTOKEN | 值为合法的 XML 名称 |
NMTOKENS | 值为合法的 XML 名称的列表 |
ENTITY | 值是一个实体 |
ENTITIES | 值是一个实体列表 |
NOTATION | 此值是符号的名称 |
xml: | 值是一个预定义的 XML 值 |
默认属性值可使用下列值 :
值 | 解释 |
---|---|
值 | 属性的默认值 |
#REQUIRED | 属性值是必需的 |
#IMPLIED | 属性不是必需的 |
#FIXED value | 属性值是固定的 |
XML解析
XML是一种通用的数据交换格式,它的平台无关性、语言无关性、系统无关性、给数据集成与交互带来了极大的方便。XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已。
XML的解析方式分为四种:1、DOM解析;2、SAX解析;3、JDOM解析;4、DOM4J解析。其中前两种属于基础方法,是官方提供的平台无关的解析方式;后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。
以下是要解析的XML文档
1 |
|
一、DOM解析
DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。
DOM接口提供了一种通过分层对象模型来访问XML文档信息的方式,这些分层对象模型依据XML的文档结构形成了一棵节点树。无论XML文档中所描述的是什么类型的信息,即便是制表数据、项目列表或一个文档,利用DOM所生成的模型都是节点树的形式。也就是说,DOM强制使用树模型来访问XML文档中的信息。由于XML本质上就是一种分层结构,所以这种描述方法是相当有效的。
DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。
优点:
1、形成了树结构,有助于更好的理解、掌握,且代码容易编写。
2、解析过程中,树结构保存在内存中,方便修改。
缺点:
1、由于文件是一次性读取,所以对内存的耗费比较大。
2、如果XML文件比较大,容易影响解析性能且可能会造成内存溢出。
以下是解析代码:
1 | package com.hyf; |
结果
1 | 开始加载books.xml文件...... |
二、SAX解析
SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。
优点:
1、采用事件驱动模式,对内存耗费比较小。
2、适用于只处理XML文件中的数据时。
缺点:
1、编码比较麻烦。
2、很难同时访问XML文件中的多处不同数据。
三、pull解析(android 推荐)
Pull内置于Android系统中。也是官方解析布局文件所使用的方式。Pull与SAX有点类似,都提供了类似的事件,如开始元素和结束元素。不同的是,SAX的事件驱动是回调相应方法,需要提供回调的方法,而后在SAX内部自动调用相应的方法。而 Pull解析器并没有强制要求提供触发的方法。因为他触发的事件不是一个方法,而是一个数字。它使用方便,效率高。
常见的解析开发包
- JAXP:sun公司提供支持DOM和SAX开发包
- JDOM:dom4j兄弟
- jsoup:一种处理html特定解析开发包
- dom4j:比较常见的解析开发包,hibernate底层采用。
DOM4J解析XML文档
jar包
下载地址:链接:http://pan.baidu.com/s/1c2LFBRa 密码:e7uc
dom4j必须使用核心类SaxReader加载xml文档获得document,通过document对象获得文档的根元素,然后就可以操作了。
解析代码
1 | package com.hyf; |
解析结果
1 | 获取根元素成功----------bookstore |
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!