XML语言
什么是XML?
XML是指可扩展标记语言(eXtensible Markup Language),它是一种标记语言,很类似HTML。它被设计的宗旨是传输数据,而非显示数据。 XML标签没有被预定义,需要用户自行定义标签。 XML技术是W3C组织(World Wide Web Consortium万维网联盟)发布的,目前遵循的是W3C组织于2000年发布的XML1.0规范。 XML被广泛认为是继Java之后在Internet上最激动人心的新技术。
XML技术用于解决什么问题?
在现实生活中存在大量有关系的数据,如右图所示。
问题:这样的数据该如何表示并交给计算机处理呢?
XML语言出现的根本目的在于描述向上图那种有关系的数据。
XML是一种通用的数据交换格式。
在XML语言中,它允许用户自定义标签。一个标签用于描述一段数据;一个标签可分为开始标签和结束标签,在起始标签之间,又可以使用其它标签描述其它数据,以此来实现数据关系的描述。
XML中的数据必须通过软件程序来解析执行或显示,如IE;这样的解析程序称之为Parser(解析器)。
<?xml version="1.0" encoding="UTF-8"?>
<中国>
<北京>
<海淀></海淀>
<丰台></丰台>
</北京>
<山东>
<济南></济南>
<青岛></青岛>
</山东>
<湖北>
<武汉></武汉>
<荆州></荆州>
</湖北>
</中国>
XML常见应用:
XML技术除用于保存有关系的数据之外,它还经常用作软件配置文件,以描述程序模块之间的关系。(如后面将要学习到的Struts、Spring和Hibernate都是基于XML作为配置文件的)
在一个软件系统中,通过XML配置文件可以提高系统的灵活性。即程序的行为是通过XML文件来配置的,而不是硬编码。
数据交换:不同语言之间用来交换数据
小型数据库:用来当数据库存储数据。
XML语法:
XML语法:
一个XML文件分为如下几部分内容:
文档声明 元素 属性 注释 CDATA区 、特殊字符 处理指令(PI:Processing Instruction)
文档声明
在编写XML文档时,需要先使用文档声明来声明XML文档。且必须出现在文档的第一行。并且必须指定
最简单的语法:
<?xml version=“1.0”?>
用encoding属性说明文档所使用的字符编码。保存在磁盘上的文件编码要与声明的编码一致。如:
<?xml version=“1.0” encoding=“GB2312”?>
用standalone属性说明文档是否独立,即是否依赖其他文档。 如:
<?xml version=“1.0” standalone=“yes”?>
yes不用引入外部的文件,no需要引入。(不常用)
元素
标签
XML元素指XML文件中出现的标签。
一个标签分为起始和结束标签(不能省略)。一个标签有如下几种书写形式:
包含标签主体:<mytag>some content</mytag>
不含标签主体:<mytag/>
一个标签中可以嵌套若干子标签,但所有标签必须合理的嵌套,不允许有交叉嵌套。
<mytag1><mytag2></mytag1></mytag2> WRONG!
一个XML文档必须有且仅有一个根标签,其他标签都是这个根标签的子标签或孙标签。
标签的空格、换行
对于XML标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的。
由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要*改变。
命名规范
一个XML元素可以包含字母、数字以及其它一些可见字符,但必须遵守下面的一些规范:
区分大小写,例如,<P>和<p>是两个不同的标记。
不能以数字或“-” (中划线)开头。
不能以xml(或XML、或Xml 等)开头。
不能包含空格。
名称中间不能包含冒号(:)。
属性
一个元素可以有多个属性,每个属性都有它自己的名称和取值,例如:<mytag name=“value” …/>
属性值一定要用引号(单引号或双引号)引起来。
属性名称的命名规范与元素的命名规范相同
元素中的属性是不允许重复的
在XML技术中,标签属性所代表的信息也可以被改成用子元素的形式来描述,例如:
<mytag>
<name>
<firstName/>
<lastName/>
</name>
</mytag>
注释
XML中的注释语法为:<!--这是注释-->
注意:
XML声明之前不能有注释
注释不能嵌套,例如:
转义字符
实体必须以符号"&"开头,以符号";"结尾。
注意: 只有"<" 字符和"&"字符对于XML来说是严格禁止使用的。剩下的都是合法的,为了减少出错,使用实体是一个好习惯。
即:< 和 & 的符号要用转义字符, > “ ‘ 可以不使用转义字符。
CDATA区
CDATA是Character Data的缩写
作用:把标签当做普通文本内容;
语法:<![CDATA[内容]]>
<![CDATA[ <itcast>www.itcast.cn</itcast> ]]>
以上红色部分被当做普通文本而不是标签
处理指令
处理指令,简称PI(Processing Instruction)。
作用:用来指挥软件如何解析XML文档。
语法:必须以“<?”作为开头,以“?>”作为结尾。 常用处理指令:
常用处理指令:
XML声明:
<?xml version=“1.0” encoding=“GB2312”?>
xml-stylesheet指令: 作用:指示XML文档所使用的CSS样式XSL。
<?xml-stylesheet type=“text/css” href=“some.css”?>
注:对中文命名的标签元素不起作用
XML语法规则总结
所有 XML 元素都须有关闭标签
XML 标签对大小写敏感 XML
必须正确地嵌套顺序
XML 文档必须有根元素(只有一个)
XML 的属性值须加引号
特殊字符必须转义 --- CDATA
XML 中的空格、回车换行会解析时被保留
XML约束:
为什么需要约束
1.XML都是用户自定义的标签,若出现小小的错误,软件程序将不能正确地获取文件中的内容而报错。(如:Tomcat)
2.XML技术中,可以编写一个文档来约束一个XML的书写规范,这个文档称之为约束。
两个概念:
格式良好的XML:遵循XML语法的XML
有效的XML:遵循约束文档的XML
3.总之:约束文档定义了在XML中允许出现的元素名称、属性及元素出现的顺序等等。
XML约束概述
1.什么是XML约束
在XML技术里,可以编写一个文档来约束一个XML
文档的书写规范,这称之为XML约束。
2.为什么需要XML约束
3.常用的约束技术
XML DTD
XML Schema
XML约束之DTD约束
DTD概述
1.DTD(Document Type Definition),全称为文档类型定义。
2.书写完成DTD,并且约束成功后,可以总结书写的过程,更方便记忆。
复杂标签:<!ELEMENT 标签名 (子节点)>
简单标签:<!ELEMENT 标签名 (#PCDATA)>
引入DTD:<!DOCTYPE 根节点 SYSTEM “dtd的地址”>
将DTD与XML文档关联三种方式
DTD约束即可以作为一个单独的文件编写,也可以在XML文件内编写
1.使用内部DTD
<!DOCTYPE 根节点 [ DTD的代码 ]>
2.使用外部DTD
<!DOCTYPE 根节点 SYSTEM “DTD的地址” >
3.使用网络DTD
<!DOCTYPE 根节点 PUBLIC “DTD的名称” “DTD的地址” >
常见的使用网络DTD约束有 Struts2的框架
在xml文件内编写DTD
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE 书架 [
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
]>
<书架>
<书>
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>39.00元</售价>
</书>
...
</书架>
引入外部DTD文档
XML使用DOCTYPE声明语句来指明它所遵循的DTD文档,有两种形式:
当引用的DTD文档在本地时,采用如下方式:
<!DOCTYPE 根元素 SYSTEM “DTD文档路径”>
如:
<!DOCTYPE 书架 SYSTEM “book.dtd”>
当引用的DTD文档在公共网络上时,采用如下方式:
<!DOCTYPE 根元素 PUBLIC “DTD名称” “DTD文档的URL”>
如:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
DTD约束语法细节
元素定义 属性定义 实体定义
元素(ELEMENT)定义
在DTD文档中使用ELEMENT关键字来声明一个XML元素。
语法:<!ELEMENT 元素名称 使用规则>
使用规则:
(#PCDATA):指示元素的主体内容只能是普通的文本.(Parsed Character Data)
EMPTY:用于指示元素的主体为空。比如<br/>
ANY:用于指示元素的主体内容为任意类型。
(子元素):指示元素中包含的子元素
定义子元素及描述它们的关系:
如果子元素用逗号分开,说明必须按照声明顺序去编写XML文档。
如: <!ELEMENT FILE (TITLE,AUTHOR,EMAIL)
如果子元素用“|”分开,说明任选其一。
如:<!ELEMENT FILE (TITLE|AUTHOR|EMAIL)
用+、*、?来表示元素出现的次数
如果元素后面没有+*?:表示必须且只能出现一次
+:表示至少出现一次,一次或多次
*:表示可有可无,零次、一次或多次
?:表示可以有也可以无,有的话只能有一次。零次或一次 如: <!ELEMENT MYFILE ((TITLE*, AUTHOR?, EMAIL)* | COMMENT)>
属性(ATTLIST)定义
属性声明举例
<!ATTLIST 商品
类别 CDATA #REQUIRED 必须的
颜色 CDATA #IMPLIED 可选的
>
对应的XML为:<商品 类别=“服装” 颜色=“黄色”/>
属性值类型
CDATA:表示属性的取值为普通的文本字符串
ENUMERATED (DTD没有此关键字):表示枚举,只能从枚举列表中任选其一,如(鸡肉|牛肉|猪肉|鱼肉)
ID:表示属性的取值不能重复(不能只写数字)
设置说明
#REQUIRED:表示该属性必须出现
#IMPLIED:表示该属性可有可无
#FIXED:表示属性的取值为一个固定值。语法:#FIXED "固定值"
直接值:表示属性的取值为该默认值
定义属性示例
<!ATTLIST 页面作者
姓名 CDATA #IMPLIED
年龄 CDATA #IMPLIED
联系信息 CDATA #REQUIRED
网站职务 CDATA #FIXED "页面作者"
个人爱好 CDATA "上网"
>
属性的类型可以是一组取值的列表,在 XML 文件中设置的属性值只能是这个列表中的某个值(枚举)
<?xml version = "1.0" encoding="GB2312" standalone="yes"?>
<!DOCTYPE 购物篮 [
<!ELEMENT 肉 EMPTY>
<!ATTLIST 肉 品种 ( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) "鸡肉">
]>
<购物篮>
<肉 品种="鱼肉"/>
<肉 品种="牛肉"/>
<肉/>
</购物篮>
表示属性的设置值为一个唯一值。
ID 属性的值只能由字母,下划线开始,不能出现空白字符
?xml version = "1.0" encoding="GB2312" ?> <!DOCTYPE 联系人列表[
<!ELEMENT 联系人列表 ANY>
<!ELEMENT 联系人(姓名,EMAIL)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>
<!ATTLIST 联系人 编号 ID #REQUIRED>
]> <联系人列表>
<联系人 编号=“p1">
<姓名>张三</姓名>
<EMAIL>zhang@it315.org</EMAIL>
</联系人>
<联系人 编号=“p2">
<姓名>李四</姓名>
<EMAIL>li@it315.org</EMAIL>
</联系人>
</联系人列表>
实体定义
实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。
在DTD定义中,一条<!ENTITY …>语句用于定义一个实体。
<!ENTITY 别名 “值”>
在元素中引用 &别名;
定义引用实体
概念:在DTD中定义,在XML中使用
语法:<!ENTITY 实体名称 “实体内容”>
引用方式(注意是在XML中使用):&实体名称;
DTD中定义: <!ENTITY copyright “博客园版权所有”>
XML中引用: ©right;
XML约束之Schema
Schema概述:
XML Schema 也是一种用于定义和描述 XML 文档结构与内容的模式语言,其出现是为了克服 DTD 的局限性
XML Schema vs DTD:
XML Schema符合XML语法结构。
DOM、SAX等XML API很容易解析出XML Schema文档中的内容。
XML Schema对名称空间支持得非常好。
XML Schema比XML DTD支持更多的数据类型,并支持用户自定义新的数据类型。
XML Schema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。
XML Schema不能像DTD一样定义实体,比DTD更复杂,但Xml Schema现在已是w3c组织的标准,它正逐步取代DTD。
好处:
XML Schema是用一套预先规定的XML元素和属性创建的,这些元素和属性定义了XML文档的结构和内容模式。 XML Schema规定XML文档实例的结构和每个元素/属性的数据类型
Schema相对于DTD的明显好处是,XML Schema文档本身也是XML文档,而不是像DTD一样使用自成一体的语法
Schema和DTD区别
XML从SGML中继承了DTD,并用它来定义内容的模型,验证和组织元素。同时,它也有很多局限:
DTD不遵守XML语法; DTD不可扩展; DTD不支持命名空间的应用; DTD没有提供强大的数据类型支持,只能表示很简单的数据类型。
Schema完全克服了这些弱点,使得基于Web的应用系统交换XML数据更为容易。下面是它所展现的一些新特性:
Schema完全基于XML语法,不需要再学习特殊的语法; Schema能用处理XML文档的工具处理,而不需要特殊的工具; Schema大大扩充了数据类型,支持booleans、numbers、dates and times、URIs、integers、decimal numbers和real numbers等; Schema支持原型,也就是元素的继承。如:我们定义了一个“联系人”数据类型,然后可以根据它产生“朋友联系人”和“客户联系”两种数据类型; Schema支持属性组。我们一般声明一些公共属性,然后可以应用于所有的元素,属性组允许把元素、属性关系放于外部定义、组合; 开放性。原来的DTD只能有一个DTD应用于一个XML文档,现在可以有多个Schema运用于一个XML文档。
Schema一些概念
XML Schema 文件自身就是一个XML文件,但它的扩展名通常为.xsd
和XML文件一样,一个XML Schema文档也必须有一个根结点,但这个根结点的名称为Schema
应用schema约束 开发xml 过程:
编写了一个XML Schema约束文档后,通常需要把这个文件中声明的元素绑定到一个URI地址上,这个URI地址叫namespace名称空间,以后XML文件就可以通过这个URI(即名称空间)引用绑定指定名称空间的元素
XMLSchema文档基本结构
在W3C XML schema规范中规定:所有的Schema文档都使用<schema>作为其根元素
<schema>元素可以包含一些属性。一个XML schema声明看起来经常以如下的形式出现
Schema入门案例
book.xsd文件
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www. itcast.cn"
elementFormDefault="qualified">
<xs:element name='书架' >
<xs:complexType>
<xs:sequence maxOccurs='unbounded' >
<xs:element name='书' >
<xs:complexType>
<xs:sequence>
<xs:element name='书名' type='xs:string' />
<xs:element name='作者' type='xs:string' />
<xs:element name='售价' type='xs:string' />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?> <itcast:书架 xmlns:itcast="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=“http://www.itcast.cn book.xsd"> <itcast:书>
<itcast:书名>九阴真经</itcast:书名>
<itcast:作者>郭靖</itcast:作者>
<itcast:售价>28.00元</itcast:售价>
</itcast:书>
</itcast:书架>
在XML Schema文档中声明名称空间
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www. itcast.cn"
elementFormDefault="qualified"
attributeFormDefault="qualified"
>
<xs:schema>
targetNamespace元素用于指定schema文档中声明的元素属于哪个名称空间。
elementFormDefault元素用于指定局部元素是否受到该schema指定targetNamespace所指定的名称空间限定
attributeFormDefault元素用于指定局部属性是否受到该schema指定targetNamespace所指定的名称空间限定
名称空间的概念:
在XML Schema中,每个约束模式文档都可以被赋以一个唯一的名称空间,名称空间用一个唯一的URI(Uniform Resource Identifier,统一资源标识符)表示。 在Xml文件中书写标签时,可以通过名称空间声明(xmlns),来声明当前编写的标签来自哪个Schema约束文档。如:
<itcast:书架 xmlns:itcast=“http://www.itcast.cn”>
<itcast:书>……</itcast:书>
</itcast:书架>
此处使用itcast来指向声明的名称,以便于后面对名称空间的引用。
注意:名称空间的名字语法容易让人混淆,尽管以 http:// 开始,那个 URL 并不指向一个包含模式定义的文件。事实上,这个 URL:http://www.itcast.cn根本没有指向任何文件,只是一个分配的名字。
使用名称空间引入Schema
为了在一个XML文档中声明它所遵循的Schema文件的具体位置,通常需要在Xml文档中的根结点中使用schemaLocation属性来指定,例如:
<itcast:书架 xmlns:itcast="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=“http://www.itcast.cn book.xsd">
schemaLocation此属性有两个值。第一个值是需要使用的命名空间。第二个值是供命名空间使用的 XML schema 的位置,两者之间用空格分隔。
注意:在使用schemaLocation属性时,也需要指定该属性来自哪里。
使用默认名称空间
基本格式:
xmlns="URI"
举例:
<书架 xmlns=" http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=“http://www.itcast.cn book.xsd">
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
使用名称空间引入多个XML Schema文档
文件清单:xmlbook.xml
<?xml version="1.0" encoding="UTF-8"?> <书架 xmlns="http://www.it315.org/xmlbook/schema"
xmlns:demo="http://www.it315.org/demo/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.it315.org/xmlbook/schema http://www.it315.org/xml/book.xsd
http://www.it315.org/demo/schema http://www.it315.org/demo.xsd">
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价 demo:币种=”人民币”>28.00元</售价>
</书>
</书架>
XML Schema基础概念
Schema元素:简单类型和复杂类型
XML Schema规范中将元素分为两种类型
简单类型元素:简单类型元素只能包含字符内容。这些字符可以被约束为特殊的预定义类型或派生类型。例如,可以指定一个简单元素的内容必须是日期、整数、字符串或者仅仅是一个字符或者一系列字符。type属性
复杂类型元素:复杂类型元素是包含子元素内容或者属性的元素 <complexType> <sequence> 子元素
Schema语法
参看w3c文档
XML编程(CRUD)
XML解析技术概述
XML解析方式分为两种:
DOM方式和SAX方式
DOM:Document Object Model,文档对象模型。这种方式是W3C推荐的处理XML的一种方式。
SAX:Simple API for XML。这种方式不是官方标准,属于开源社区XML-DEV,几乎所有的XML解析器都支持它。
XML解析开发包 :
JAXP:是SUN公司推出的解析标准实现。
Dom4J:是开源组织推出的解析开发包。(牛,大家都在用,包括SUN公司的一些技术的实现都在用) J
Dom:是开源组织推出的解析开发包。
JAXP:
JAXP:(Java API for XML Processing)开发包是JavaSE的一部分,它由以下几个包及其子包组成:
org.w3c.dom:提供DOM方式解析XML的标准接口
org.xml.sax:提供SAX方式解析XML的标准接口
javax.xml:提供了解析XML文档的类
javax.xml.parsers包中,定义了几个工厂类。我们可以通过调用这些工厂类,得到对XML文档进行解析的DOM和SAX解析器对象。 DocumentBuilderFactory
SAXParserFactory
DOM解析:
使用JAXP进行DOM解析
javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对象 , DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。
获得JAXP中的DOM解析器
调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂。
调用工厂对象的 newDocumentBuilder方法得到 DOM 解析器对象。
调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,进行可以利用DOM特性对整个XML文档进行操作了。
DOM编程介绍
DOM模型(document object model)
DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。
在dom中,节点之间关系如下:
位于一个节点之上的节点是该节点的父节点(parent)
一个节点之下的节点是该节点的子节点(children)
同一层次,具有相同父节点的节点是兄弟节点(sibling)
一个节点的下一个层次的节点集合是节点后代(descendant)
父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)
节点类型:Node对象
Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。(查看API文档)
Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。
DOM方式解析XML文件
DOM解析编程:
1获取指定节点的集合
2查找某一个节点
3删除结点
4更新结点内容
5添加节点
6获取所有的节点的名称(递归遍历)
具体步骤为:
1通过document.getElementsByTagName(“”) 可以获取节点集合 返回NodeList
2通过Document.createElement(“”)可以创建元素对象。
3Node对象中可以设置文本内容 setTextContent()
4通过Node的appendChild()方法加入子节点。
5需要把内存中的DOM树形结构回写到xml文件中。
6TransformerFactory工厂类创建Transformer回写类,通过transform(Souuce,Result)方法回写xml。
7New DOMSource(document) 和 new StreamResult(xml) 回写完成。
8递归方法就是自己调用自己
public static void getNodeName(Node node){
if(node.getNodeType() == Node.ELEMENT_NODE){
System.out.println(node.getNodeName());
}
NodeList nodeList = node.getChildNodes();
for(int i=0;i<nodeList.getLength();i++){
Node child = nodeList.item(i);
getNodeName(child);
}
}
更新XML文档
javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。
Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:
javax.xml.transform.dom.DOMSource类来关联要转换的document对象
用javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。
Transformer对象通过TransformerFactory获得。
SAX解析:
SAX解析的优点:
在使用 DOM 解析 XML 文档时,需要读取整个 XML 文档,在内存中构架代表整个 DOM 树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果 XML 文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。
SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作
解析器和事件处理器:
SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器 和事件处理器:
解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。
SAX解析原理:
SAX 是事件驱动的 XML 处理方法
它是基于事件驱动的
startElement() 回调在每次 SAX 解析器遇到元素的起始标记时被调用
characters() 回调为字符数据所调用
endElement() 为元素的结束标记所调用
DefaultHandler类(在 org.xml.sax.helpers 软件包中)来实现所有这些回调,并提供所有回调方法默认的空实现
SAX的事件驱动模型:
SAX DocumentHandler示例
SAX 解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件
发生相应事件时,将调用一个回调方法
<?xml version=“1.0” encoding=“utf-8”?>
<config>
<server>UNIX</server>
</config>
Start document
Start element (config)
Characters (whitespace)
Start element (server)
Characters (UNIX)
End element (server)
Characters (whitespace)
End element (config)
End document
使用SAX方式解析XML:
使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
通过解析器对象解析xml文件 xmlReader.parse("book.xml“,new XMLContentHandler());
这里的XMLContentHandler 继承 DefaultHandler
SAX 代码例子
public class XMLContentHandler extends DefaultHandler{
//当前元素中的数据
private String currentData;
//取得元素数据
public void characters(char[] ch, int start, int length)
throws SAXException {
currentData=new String(ch,start,length);
}
//在解析整个文档结束时调用
public void endDocument() throws SAXException {
System.out.println("结束文档");
}
//在解析元素结束时调用
public void endElement(String uri, String localName, String name)
throws SAXException {
System.out.println("节点数据 *************************"+this.currentData);
System.out.println("结束元素 ************"+name);
} //在解析整个文档开始时调用
public void startDocument() throws SAXException {
System.out.println("开始文档");
} //在解析元素开始时调用
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
System.out.println("开始元素 ************"+name);
}
}
DOM解析和SAX解析总结:
通过dom.xml的文件画图解析DOM和SAX的关系
首先DOM解析XML也是在内存中形成一个树状结构。
DOM解析:把整个XML文档先加载到内存中,形成树状结构。
缺点:如果文档非常大,加载到内存中容易产生内存溢出的问题。
优点:因为节点与节点之间有关系,进行增删改非常方便。
SAX解析:基于事件驱动的,边读边解析。
缺点:不能进行增删改的操作。
优点:文档大也不会有内存溢出的问题,查找非常方便。
DOM4J解析XML文档:
Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。
使用Dom4j开发,需下载dom4j相应的jar文件。
Document对象
DOM4j中,获得Document对象的方式有三种:
1.读取XML文件,获得document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
2.解析XML形式的文本,得到document对象.
String text = "<members></members>";
Document document = DocumentHelper.parseText(text);
3.主动创建document对象.
Document document = DocumentHelper.createDocument();
//创建根节点
Element root = document.addElement("members");
节点对象
1.获取文档的根节点.
Element root = document.getRootElement();
2.取得某个节点的子节点.
Element element=node.element(“书名");
3.取得节点的文字
String text=node.getText();
4.取得某节点下所有名为“member”的子节点,并进行遍历.
List nodes = rootElm.elements("member");
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element elm = (Element) it.next();
// do something }
5.对某节点下的所有子节点进行遍历.
for(Iterator it=root.elementIterator();it.hasNext();){
Element element = (Element) it.next();
// do something }
6.在某节点下添加子节点.
Element ageElm = newMemberElm.addElement("age");
7.设置节点文字.
element.setText("29");
8.删除某节点.
//childElm是待删除的节点,parentElm是其父节点
parentElm.remove(childElm);
9.添加一个CDATA节点.
Element contentElm = infoElm.addElement("content");
contentElm.addCDATA(diary.getContent());
节点对象属性
1.取得某节点下的某属性
Element root=document.getRootElement();
//属性名name Attribute attribute=root.attribute("size");
2.取得属性的文字
String text=attribute.getText();
3.删除某属性
Attribute attribute=root.attribute("size");
root.remove(attribute);
4.遍历某节点的所有属性
Element root=document.getRootElement();
for(Iterator it=root.attributeIterator();it.hasNext();){
Attribute attribute = (Attribute) it.next();
String text=attribute.getText();
System.out.println(text); }
5.设置某节点的属性和文字.
newMemberElm.addAttribute("name", "sitinspring");
6.设置属性的文字
Attribute attribute=root.attribute("name");
attribute.setText("sitinspring");
将文档写入XML文件
1.文档中全为英文,不设置编码,直接写入的形式.
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(document);
writer.close();
2.文档中含有中文,设置编码格式写入的形式.
OutputFormat format = OutputFormat.createPrettyPrint();
// 指定XML编码
format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
writer.write(document);
writer.close();
Dom4j在指定位置插入节点
1.得到插入位置的节点列表(list)
2.调用list.add(index,elemnent),由index决定element的插入位置。
Element元素可以通过DocumentHelper对象得到。示例代码:
Element aaa = DocumentHelper.createElement("aaa");
aaa.setText("aaa");
List list = root.element("书").elements();
list.add(1, aaa);
//更新document
字符串与XML的转换
1.将字符串转化为XML
String text = "<members> <member>sitinspring</member></members>";
Document document = DocumentHelper.parseText(text);
2.将文档或节点的XML转化为字符串.
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
Element root=document.getRootElement();
String docXmlText=document.asXML();
String rootXmlText=root.asXML();
Element memberElm=root.element("member");
String memberXmlText=memberElm.asXML();