JavaWeb之XML详解

XML语言

什么是XML?

  XML是指可扩展标记语言(eXtensible Markup Language),它是一种标记语言,很类似HTML。它被设计的宗旨是传输数据,而非显示数据。 XML标签没有被预定义,需要用户自行定义标签。 XML技术是W3C组织(World Wide Web Consortium万维网联盟)发布的,目前遵循的是W3C组织于2000年发布的XML1.0规范。 XML被广泛认为是继Java之后在Internet上最激动人心的新技术。

XML技术用于解决什么问题?

  在现实生活中存在大量有关系的数据,如右图所示。

JavaWeb之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解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的。

JavaWeb之XML详解

由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要*改变。

命名规范

一个XML元素可以包含字母、数字以及其它一些可见字符,但必须遵守下面的一些规范:

  区分大小写,例如,<P>和<p>是两个不同的标记。

  不能以数字或“-” (中划线)开头。

  不能以xml(或XML、或Xml 等)开头。

  不能包含空格。

  名称中间不能包含冒号(:)。

属性

一个元素可以有多个属性,每个属性都有它自己的名称和取值,例如:<mytag name=“value” …/>

属性值一定要用引号(单引号或双引号)引起来。

属性名称的命名规范与元素的命名规范相同

元素中的属性是不允许重复的

在XML技术中,标签属性所代表的信息也可以被改成用子元素的形式来描述,例如:

<mytag>
<name>
<firstName/>
<lastName/>
</name>
</mytag>

注释

XML中的注释语法为:<!--这是注释-->

注意:

  XML声明之前不能有注释

  注释不能嵌套,例如:

  JavaWeb之XML详解

转义字符

  JavaWeb之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),全称为文档类型定义。

  JavaWeb之XML详解

  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:用于指示元素的主体内容为任意类型。

      (子元素):指示元素中包含的子元素

JavaWeb之XML详解

    定义子元素及描述它们的关系:

      如果子元素用逗号分开,说明必须按照声明顺序去编写XML文档。

       如: <!ELEMENT FILE (TITLE,AUTHOR,EMAIL)

      如果子元素用“|”分开,说明任选其一。

       如:<!ELEMENT FILE (TITLE|AUTHOR|EMAIL)

      用+、*、?来表示元素出现的次数

        如果元素后面没有+*?:表示必须且只能出现一次

        +:表示至少出现一次,一次或多次

        *:表示可有可无,零次、一次或多次

        ?:表示可以有也可以无,有的话只能有一次。零次或一次 如: <!ELEMENT MYFILE ((TITLE*, AUTHOR?, EMAIL)* | COMMENT)>

JavaWeb之XML详解

属性(ATTLIST)定义

JavaWeb之XML详解

  属性声明举例
<!ATTLIST 商品
类别 CDATA #REQUIRED 必须的
颜色 CDATA #IMPLIED 可选的
>

  对应的XML为:<商品 类别=“服装” 颜色=“黄色”/>

  属性值类型

  CDATA:表示属性的取值为普通的文本字符串

  ENUMERATED (DTD没有此关键字):表示枚举,只能从枚举列表中任选其一,如(鸡肉|牛肉|猪肉|鱼肉)

  ID:表示属性的取值不能重复(不能只写数字)

  设置说明

  #REQUIRED:表示该属性必须出现

  #IMPLIED:表示该属性可有可无

  #FIXED:表示属性的取值为一个固定值。语法:#FIXED "固定值"

  直接值:表示属性的取值为该默认值

JavaWeb之XML详解

  定义属性示例
<!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中引用: &copyright;

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 过程:

JavaWeb之XML详解

编写了一个XML Schema约束文档后,通常需要把这个文件中声明的元素绑定到一个URI地址上,这个URI地址叫namespace名称空间,以后XML文件就可以通过这个URI(即名称空间)引用绑定指定名称空间的元素

XMLSchema文档基本结构

在W3C XML schema规范中规定:所有的Schema文档都使用<schema>作为其根元素

JavaWeb之XML详解

<schema>元素可以包含一些属性。一个XML schema声明看起来经常以如下的形式出现

JavaWeb之XML详解

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方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。

JavaWeb之XML详解

获得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的事件驱动模型:

  JavaWeb之XML详解

  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解析总结:

JavaWeb之XML详解

通过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();

上一篇:javaweb之监听器详解


下一篇:javaweb之Filter详解(转)