xml视频笔记

 

1、xml发展历史

   xml全称为Extensible Markup Language,可扩展标记语言;是由W3C组织发布的,目前遵循的是W3C组织于2000年发布的xml.0规范。

   1969gml(通用标记语言)主要目的是在不同的机器上进行通信的数据规范

   1985sgml(标准通用标记语言)

   1993html(www)

   Html语言本身是是由一些缺陷的,比如

   1)标记不能自定义


<html>

       <body>

              <table>

                     <td>123</td>

              </table>

       </body>

</html>

2html本身缺少一些含义

<html>

       <body>

               <h1>水浒英雄</h1>

              <table>

                     <tr>

                            <td>宋江</td>

                     </tr>

              </table>

       </body>

</html>

3html本身没有真正的国际化

2、为什么需要学习xml

1xml的出现解决了程序间数据传输的问题;

     比如QQ之间的数据用xml格式来传递,具有良好的可读性和可维护性;

2)可以用做配置文件;

3)可以充当小型的数据库;

     因为直接读取文件显然要比读取数据库更快。

3、xml语法

入门案例:使用xml来记录一个班级的信息

<?xml version="1.0" encoding="gb2312"?>

<class>

       <stu id="001">

              <name>杨过</name>

              <sex></sex>

              <age>30</age>

       </stu>

       <stu id="002">

           <name>小龙女</name>

              <sex></sex>

              <age>30</age>

       </stu>

</class>

一个xml文件分为如下几个部分内容:

3.1、文档声明

<?xml version="1.0" encoding="gb2312"?>

axml声明放在xml文档的第一行;

bxml声明由以下几个部分组成:

  version——文档符合xml1.0规范

  encoding——文档字符编码,比如“utf-8”,“gb2312”;

  standalone——文档定义是否独立使用,默认是“no”;

3.2、元素

   a、每个xml文档必须有且仅有一个根元素;

   b、根元素是一个完全包括文档中其他所有元素的元素;

   c、根元素的起始标记要放在所有其他元素的起始标记之前;

   d、根元素的结束标记要放在所有其他元素的结束标记之后;

   exml元素指xml文件中出现的标签,一个标签分为开始标签和结束标签,主要有以下两种标签格式:

         包含标签体:<a>www</a>

               不包含标签体:<a></a>,简写为</a>

   f、一个标签中可以嵌套若干个子标签,但所有标签必须是合理的嵌套,决不允许交、叉嵌套;

   g、对于xml标签中出现的所有空格和换行,xml解析程序都会当做标签内容进行处理,因此在编写xml文件时要特别注意空格和换行;

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

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

l         不能艺术字或“_”(下划线)开头;

l         不能包含空格;

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

3.3、属性

   a、属性值用双引号或单引号分隔;

   b、一个元素可以有多个属性,它的基本格式为:<元素名属性名=”属性值”>

       c、特定的属性名称在同一个元素标记中只能出现一次;

       d、属性值不能包括<,>,&.

3.4、注释

   a、注释内容中不要出现--

   b、不要把注释放在标记中间;

   c、注释不能嵌套;

   d、可以在除标记以外的任何地方放注释;

   e、注释采用:“<!—注释-->”格式;

   注意:xml声明之前不能有注释。

3.5CDATA区、特殊字符

   a、有些内容可能不想让解析引擎解析执行,而是当做原始内容来处理,用于把整段文本解释为纯字符数据而不是标记的情况。CDATA节中的所有字符都会被当做元素字符数据的常量部分,而不是xml标记。

  b、语法形式:

    <![CDATA[。。。。。]]>

  c、可以输入任意字符,当然是除]]>之外了;

  d、不可以嵌套使用。

  e、转义字符

     对于一些单个字符,若执行显示其原始样式,也可以使用转义的形式予以处理

     转义符

符号

&lt;

&gt;

&amp;

&

&quot;

&apos;

3.6、处理指令(processing instruction

   a、处理指令,简称PI,处理指令用来指挥解析引擎如何解析xml文档内容;

   b、在xml文档中使用xml-stylesheet指令,通知xml解析引擎,应用css文件显示xml文档内容,格式如下:

<?xml-stylesheet type="text/css" href="。。.css"?>

myClass.xml文件中引入my.css样式:

name{

       font-size:100px;

       font-weight:bold;

       color:red;

}

age{

       font-size:50px;

       font-weight:bold;

       color:blue;

}

sex{

       font-size:20px;

       font-weight:bold;

       color:yellow;

}

修改后的myClass.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>

<?xml-stylesheet type="text/css" href="my.css"?>  

<class>

       <stu id="001">

              <name>杨过</name>

              <sex></sex>

              <age>30</age>

       </stu>

       <stu id="002">

           <name>小龙女</name>

              <sex></sex>

              <age>30</age>

       </stu>

</class>

注意:编码问题

ansi编码:美国国家标准协会制定的编码格式标准,在不同的国家是不一样的,比如在中国是gb2312

总结:

遵循如下规则的xml文档称为正规的xml文档:

l         语法规范

a、包含xml声明语句;

b、必须有且仅有一个根元素;

c、标记大小写敏感;

d、属性值用引号;

e、标记成对且空标记关闭;

f、元素正确嵌套。

l         元素语法

a、名称中可以包含字母、数字或者其它字符;

b、名称中不能包含空格;

c、名称中不能含有冒号(注:冒号留给命名空间使用)。

4、xml文件约束

4.1xml约束概述

       xml约束是指通过编写一个文档来约束一个xml文档的书写规范,常用的约束技术是XML  DTDXML Schema

4.2DTD约束

       DTD(Document Type Defintion),全称为文档类型定义。

axmlDTD之间的关系如下图所示:

    b、基本语法:

<!ELEMENT 元素名类型>

c、快速入门案例:

    编写myClass2.xml文件和myClass2.dtd文件,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE 班级 SYSTEM "myClass2.dtd">

<班级>

       <学生>

              <姓名>周星驰</姓名>

              <年龄>23</年龄>

              <介绍>学习刻苦</介绍>

       </学生>

       <学生>

              <姓名>林青霞</姓名>

              <年龄>45</年龄>

              <介绍>认真</介绍>

       </学生>

</班级>

<!ELEMENT 班级 (学生+)>

       <!ELEMENT 学生 (姓名,年龄,介绍)>

       <!ELEMENT 姓名 (#PCDATA)>

       <!ELEMENT 年龄 (#PCDATA)>

       <!ELEMENT 介绍 (#PCDATA)>

编写校验xml文档正确项的解析工具,在IE5以上浏览器内置了xml解析工具,也可通过xmlspy工具进行验证;

主要步骤如下:

1、创建xml文档解析器对象

2、开启xml校验

3、装载xml文档

4、获取错误信息

实现代码如下所示:

<html>

       <head>

              <title>my xml verfiy tool</title>

              <script language="javascript">

              <!--

                     var xmldoc = new ActiveXObject("Microsoft XMLDOM");

                     xmldoc.validateOnParse ="true";//开启校验

                     xmldoc.load("myClass2.xml");//指定校验哪个xml文件

                     document.writeln("错误信息是:"+xmldoc.parseError.Error);

                     document.writeln("错误信息所在行:"+xmldoc.parseError.line);

              -->

              </script>

       </head>

</html>

dDTD文档的声明以及引用

   内部DTD文档

<!DOCTYPE 根元素 [定义内容]>

   示例:

<?xml version="1.0" encoding="gb2312"?>

<!DOCTYPE poem[

       <!DOCTYPE poem (author,title,content)>

       <!ELEMENT author (#PCDATA)>

       <!ELEMENT title (#PCDATA)>

       <!ELEMENT content (#PCDATA)>

]>

<poem>

       <author>王维</author>

       <title>鹿柴</title>

       <content>空山不见人,但闻人语声。

                      返景入深林,复照青苔上。        

       </content>

</poem>

注意:例中的定义关键字一定要大写,比如DOCTYPE,ELEMENT,#PCDATA,且元素名称与数据类型之间也要有空格。

外部DTD文档

<!DOCTYPE 根元素 SYSTEM  “DTD文件路径”>

   示例见入门案例。

内外部DTD文档结合

<!DOCTYPE 根元素 SYSTEM “DTD文件路径”[定义内容]>

xml文件使用DOCTYPE声明语句来指明它所遵循的DTD文件,DOCTYPE声明语句有两种形式:

l         当引用的文件在本地时,采用如下方式:

<!DOCTYPE 文档根结点 SYSTEM “DTD文件的URL”>

l         当引用的文件时一个公共的文件时,采用如下形式:

<!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">

eDTD元素

l         语法

<!ELEMENT NAME CONTENT>

以上三个单词分别对应关键字、元素名称、元素类型(大写);

CONTENT包括以下三种:

1EMPTY:该元素不能包含子元素和文本,但是可以有属性(即空元素);

示例:

<!ELEMENT  EMPTY>

<家庭>

       <人名字="皮诺曹"性别=""年龄="6"/>

</家庭>

2ANY:该元素可以包含任何在DTD中定义的元素内容;

示例:

<!ELEMENT  ANY>

<家庭>

       <>皮诺曹</>

       <><大人>皮诺曹爸爸</大人></>

</家庭>

3#PCDATA:可以包含任何字符数据,但是不能再其中包含任何子元素其它类型(组合)。

<!ELEMENT  (#PCDATA)>

<家庭>

       <人性别=""年龄="6">皮诺曹</>

</家庭>

组合类型如下所示:

<!ELEMENT 家庭 (+,家电*)>

<家庭>

       <人名字="郭大路"性别=""年龄="25"/>

       <人名字="李寻欢"性别=""年龄="38"爱好="作个教育家和伟人"/>

       <家电名称="彩电"数量="3"/>

</家庭>

修饰符如下所示:

编号

符号

用途

示例

示例说明

1

( )

用来给元素分组

(古龙|金庸),(王朔|余杰),三毛

分成三组

2

|

在列中的对象中选择一个

(男人|女人)

表示男人或者女人必须出现,两者至少选一

3

+

该对象最少出现一次,可以出现多次

(成员+)

表示成员必须出现,而且可以出现多个成员

4

*

该对象允许出现零次到人一多次

(爱好*)

爱好可以出现零次到多次

5

?

该对象可以出现,但是只能出现一次(01次)

(菜鸟?)

菜鸟可以出现,也可以不出现,但是如果出现的话,最多只能出现一次

6

,

对象必须按指定的顺序出现

(西瓜,苹果,香蕉)

表示西瓜,苹果,香蕉必须出现,并且按这个顺序出现

4.3、属性

a、语法:

<!ATTLIST 元素名称

       属性名称类型属性特点

       属性名称类型属性特点...

其中类型包括四种:CDATAIDIDREF/IDREFSEnumeratedENTITY/ENTITIES

属性特点包括四种:#REQUIRED#IMPLIED#FIXED value#Default value

b、属性类型:

l         CDATA:属性值可以使任何字符(包括数字和中文)

<!ATTLIST 木偶

       姓名 CDATA #REQUIRED

<木偶姓名="dirk">

<木偶姓名="德克">

<木偶姓名="dirk41">

l         ID:表明该属性的取值必须是唯一的。

<!ELEMENT 公司职员 ANY>

<!ATTLIST 公司职员

  编号 ID #REQUIRED

  姓名 CDATA #REQUIRED

<公司职员编号="1001"姓名="张三">

<公司职员编号="1002"姓名="李四">

l         IDREF/IDREFSIDREF属性的值指向文档中其它地方声明的ID类型的值;

                   IDREFSIDREF,但是可以具有由空格分开的多个引用。

<!ELEMENT 家庭(+)>

<!ELEMENT  EMPTY>

<!ATTLIST 

       relID ID #REQUIRED

       parentID IDREFS #IMPLIED

       name CDATA #REUIRED

<家庭>

       < relID="p01" name="爸爸">

       < relID="p02" name="妈妈">

       < relID="p03" parentID="p01 02" name="儿子">

</家庭>

l         Enumerated:事先定义好一些值,属性的值必须在所列出的值的范围内。

<!ATTLIST person 婚姻状态(single|married|divorced|widowed) #IMPLIED>

<!ATTLIST person 性别(|) #REQUIRED>

c、属性的特点:

l         #REQUIRED:元素的所有实例都必须有该属性的值(NOT NULL)。

语法:

<!ATTLIST 元素名属性名属性类型 #REQUIRED>

示例:

<!ATTLIST person number CDATA #REQUIRED>

<person number="5678"/>

l         #IMPLIED:元素的实例中可以忽略该属性(NULL)。

语法:

<!ATTLIST 元素名属性名属性类型 #IMPLIED>

示例:

<!ATTLIST contact fax CDATA #IMPLIED>

<contact fax="555-667788">

l         #FIXED value:元素实例中该属性的值必须为指定的固定值。

语法:

<!ATTLIST 元素名属性名属性类型 #FIXED "value">

示例:

<!ATTLIST sender company CDATA #FIXED "Microsoft">

<sender company="Microsofr"/>

l         Default value:为属性听过一个默认的值。

语法:

<!ATTLIST 元素名属性名类型 "value">

示例:

<!ATTLIST payment type CDATA "check">

<payment type="check"/>

d、实体:

l         定义:是用于为一段内容创建一个别名,以后再xml文档中就可以使用别名引用这段内容了,在DTD定义中,一条<!ENTITY ...>语句用于定义一个实体;实体可以分为两种类型:引用类型和参数实体。

l         引用实体:主要在xml文档中被应用;

语法:

<!ENTITY 实体名称 "实体内容">:直接转变成实体内容

引用方式:

&实体名称;

示例:

<!ENTITY copyright "I am a coder">

&copyright;

l         参数实体:被DTD文档自身使用;

语法:

<!ENTITY  %实体名称 "实体内容">

引用方式:

%实体名称;

示例:

<!ENTITY % TAG_NAMES "姓名|EMAIL|电话|地址">

<!ENTITY 个人信息 (%TAG_NAME;|生日)>

<!ENTITY 客户信息 (%TAG_NAME;|公司名)>

<!ENTITY %common.attributes

       id ID #IMPLIED

       account CDATA #REQUIRED

...

<!ATTLIST purchaseOrder %common.attributes;>

<!ATTLIST item %commo.attributes;>

       e、练习:

根据以下的dtd文件写出相对应的xml文件:

     1)报纸文章 DTD

!DOCTYPE NEWSPAPER [

<!ELEMENT NEWSPAPER (ARTICLE+)>

<!ELEMENT ARTICLE (HEADLINE,BYLINE,LEAD,BODY,NOTES)>

<!ELEMENT HEADLINE (#PCDATA)>

<!ELEMENT BYLINE (#PCDATA)>

<!ELEMENT LEAD (#PCDATA)>

<!ELEMENT BODY (#PCDATA)>

<!ELEMENT NOTES (#PCDATA)>

<!ATTLIST ARTICLE AUTHOR CDATA #REQUIRED>

<!ATTLIST ARTICLE EDITOR CDATA #IMPLIED>

<!ATTLIST ARTICLE DATE CDATA #IMPLIED>

<!ATTLIST ARTICLE EDITION CDATA #IMPLIED>

<!ENTITY NEWSPAPER "Vervet Logic Times">

<!ENTITY PUBLISHER "Vervet Logic Press">

<!ENTITY COPYRIGHT "Copyright 1998 Vervet Logic Press">

]>

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE NEWSPAPER SYSTEM "newspaper.dtd">

<NEWSPAPER>

       <ARTICLE AUTHOR="steven" EDITOR="dirk" DATE="2012" EDITION="china">

              <HEADLINE>let us go mavs</HEADLINE>

              <BYLINE>let us go dirk</BYLINE>

              <LEAD>Mavs</LEAD>

              <BODY>huangwenbo</BODY>

              <NOTES>sanjiangunivesity</NOTES>

       </ARTICLE>

</NEWSPAPER>

 2)产品目录 DTD

<!DOCTYPE CATALOG [

<!ENTITY AUTHOR "John Doe">

<!ENTITY COMPANY "JD Power Tools, Inc.">

<!ENTITY EMAIL "[email protected]">

<!ELEMENT CATALOG (PRODUCT+)>

<!ELEMENT PRODUCT

(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>

<!ATTLIST PRODUCT

NAME CDATA #IMPLIED

CATEGORY (HandTool|Table|Shop-Professional) "HandTool"

PARTNUM CDATA #IMPLIED

PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"

INVENTORY (InStock|Backordered|Discontinued) "InStock">

<!ELEMENT SPECIFICATIONS (#PCDATA)>

<!ATTLIST SPECIFICATIONS

WEIGHT CDATA #IMPLIED

POWER CDATA #IMPLIED>

<!ELEMENT OPTIONS (#PCDATA)>

<!ATTLIST OPTIONS

FINISH (Metal|Polished|Matte) "Matte"

ADAPTER (Included|Optional|NotApplicable) "Included"

CASE (HardShell|Soft|NotApplicable) "HardShell">

<!ELEMENT PRICE (#PCDATA)>

<!ATTLIST PRICE

MSRP CDATA #IMPLIED

WHOLESALE CDATA #IMPLIED

STREET CDATA #IMPLIED

SHIPPING CDATA #IMPLIED>

<!ELEMENT NOTES (#PCDATA)>

]>

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE CATALOG SYSTEM "product.dtd">

<CATALOG>

       <PRODUCT NAME="lenovo" CATEGORY="HandTool" PARTNUM="abc" PLANT="Chicago" INVENTORY="InStock">

              <SPECIFICATIONS WEIGHT="800" POWER="600">lenove y460p</SPECIFICATIONS>

              <OPTIONS FINISH="Matte" ADAPTER="Included" CASE="HardShell">123</OPTIONS>

              <PRICE>100</PRICE>

       </PRODUCT>

</CATALOG>

4.4xml Schema

l         xml Schema也是一种用于定义和描述XML文档结构与内容的模式语言,其出现是为了克服DTD的局限性。

l         xml Schema的特点:

axml Schemadtd更加符合XML语法结构,因为xml Schema自身就是xml文件,为了有所区别,扩展名通常为.xsd

bxml解析器很容易解析出xml Schema文档中的内容;

cxml SchemaXML DTD支持更多的数据类型,并支持用户自定义新的数据类型;

dxml Schema对名称空间支持的非常好;

exml Schema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。

l         一个XML Schema文档通常称之为模式文档(约束文档),遵循这个文档书写的xml文件称之为实例文档。

l         和xml文件一样,一个xml Schema文档也必须有一个根结点,但这个根结点的名称为Schema

l         编写一个xml Schema岳苏文档后,通常需要把这个文件中的声明的元素绑定到一个uri地址上,在xml Schema技术中有一个专业术语来描述这个过程,即把XML Schema文档声明的元素绑定到一个名称空间上,以后xml文件就可以通过这个URI(即名称空间)来告诉解析引擎,xml文档正编写的元素来自哪里,被谁约束。

关于名称空间的注意点:

l         为什么要声明名称空间:由于xml文档可以被任何组织或个人定义,这就完全有可能在一个xml文件中出现重复的元素,此时使用名称空间可以加以区分。

l         在xml Schema中,每个模式文档都可以被赋以一个唯一的名称空间,名称空间用一个唯一的URIUniform Resource Identifier,统一资源标示符)表示。

比如:xml文件中的内容:

<itcast:书架 xmlns:itcast="http://www.itcast.cn">

       <itcast:>....</itcast:>

</itcast>

    此处使用itcast来指向声明的名称,以便于后面对名称空间的引用。

l         名称空间中的uri虽然是以http//开头,但是它可以不指向任何一个真实的地址,而仅仅是作为一个名称空间来声明。

快速入门案例:

编写book.xsd文件来约束book.xml文件,代码如下所示:

<?xml version="1.0" encoding="UTF-8" ?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

                                   targetNamespace="http://wwwtcast.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:书名>

                     Javascript网页开发

              </itcast:书名>

              <itcast:作者>

                    张孝祥

              </itcast:作者>

              <itcast:售价>

                     28.00

              </itcast:售价>

       </itcast:>

</itcast:书架>

使用默认名称空间

l         基本格式:

xmlns=”URI”

l         举例:

<?xml version="1.0" encoding="utf-8"?>

<书架 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:noNamespaceSchemaLocation="xmlbook.xsd">

       <>

              <书名>

                     Javascript网页开发

              </书名>

              <作者>

                    张孝祥

              </作者>

              <售价>

                     28.00

              </售价>

       </>

</书架>

5、xml编程

5.1xml解析技术的介绍

5.1.1xml解析分为:dom解析和sax解析

dom:Document Object Model,即文档对象模型,是W3C组织推荐的处理xml的一种方式;

sax:Simple API for xml,不是官方标准,但它是xml社区事实上的标准,几乎所有的xml解析器都支持它。

5.1.2JAXP介绍

l         JAXP开发包是J2SE的一部分,它由javax.xmlorg.w3c.domorg.xml.sax包及其子包组成;

l         在javax.xml.parsers包中,定义了几个工厂类,程序员调用这些工厂类就可以得到对xml文档进行接卸的DOMSAX的解析器对象。

       5.1.3、获得JAXP中的DOM解析器的步骤

l         1、调用DocumentBuilderFactory.newInstance()方法得到创建DOM解析器的工厂。

l         2、调用工厂对象的new DocumentBuilder方法得到DOM解析器对象。

l         3、调用DOM解析器对象的parse()方法解析xml文档,得到代表整个文档的Document对象,进行可以利用DOM特性对整个xml文档进行操作了。

5.2DOM编程

l         DOM 模型就是Document Object Model

l         DOM 解析器在解析XML文档给时,会把文档的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点);

l         在DOM中,节点之间关系如下所示:

1)位于一个节点之上的节点是该节点的父节点(parent);

2)一个节点之下的节点是该节点的子节点(children);

3)同一层次,具有相同父节点的节点是兄弟节点(sibling);

4)一个节点的下一个层次的节点是兄弟节点(descendant);

5)父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)。

          xml DOM的解析图如下所示:

 

       5.2.1Node对象

l         Node对象提供了一系列常量来代表节点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便调用其特有的方法,

l         Node对象提供了相应的方法去获得它的父节点或自己点。

       5.2.2、更新XML文档

l         javax.xml.transform包中的Transformer类用于把代表xml文件的Document对象转换成某个格式后进行输出,例如把xml文件应用样式表后转换成一个html文档。利用这个对象,也可以把Document对象用重新写入到一个xml文件中;

l         Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地;

l         Transformer对象通过TransformerFactory获得。

       5.2.3JAXP实例:

            class.xml文件进行CRUD操作,class.xml中代码如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<班级>

       <学生>

              <姓名>周星驰</姓名>

              <年龄>23</年龄>

              <介绍>学习刻苦</介绍>

       </学生>

       <学生 >

              <姓名>林青霞</姓名>

              <年龄>45</年龄>

              <介绍>认真</介绍>

       </学生>

</班级>

DomXml1.java代码如下所示:

package com.hwb;

 

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

 

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

 

public class DomXml1 {

       public static void main(String[] args) throws Exception {

              // 利用dom技术对xml文件进行CRUD操作

              // 创建一个DocumentBuilderFactory

              DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

              // 通过DocumentBuilderFactory得到一个DocumentBuilder对象

              DocumentBuilder dBuilder = dbf.newDocumentBuilder();

              // 指定解析xml文件的地址

              Document document = dBuilder.parse("src/class.xml");

              // 遍历xml文件

              list(document);

              // 查询某个学生的信息(假设取出第一个学生的信息)

              read(document);

              // 添加一个学生到xml文件中

              add(document);

              // xml文件中删除一个学生信息

              delete(document);

              // 更改xml文件中某个学生的信息

              update(document);

       }

 

       public static void update(Document document) throws Exception {

              // 首先找到需要更改的节点并作出修改

              Element node = (Element) document.getElementsByTagName("学生").item(0);

              Element node_name = (Element) document.getElementsByTagName("姓名").item(

                            0);

              node_name.setTextContent("宋江");

              // 更新xml文件

              // 得到TransformerFactory

              TransformerFactory tff = TransformerFactory.newInstance();

              // 通过TransformerFactory得到一个转换器

              Transformer tf = tff.newTransformer();

              tf

                            .transform(new DOMSource(document), new StreamResult(

                                          "src/class.xml"));

 

       }

 

       public static void delete(Document document) throws Exception {

              // 删除属性sex

              Element node = (Element) document.getElementsByTagName("学生").item(0);

              node.removeAttribute("sex");

              // 更新xml文件

              // 得到TransformerFactory

              TransformerFactory tff = TransformerFactory.newInstance();

              // 通过TransformerFactory得到一个转换器

              Transformer tf = tff.newTransformer();

              tf

                            .transform(new DOMSource(document), new StreamResult(

                                          "src/class.xml"));

       }

 

       public static void add(Document document) throws Exception {

              // 创建一个新的学生的节点

              Element newStu = document.createElement("学生");

              // 为学生添加属性

              newStu.setAttribute("sex", "");

              // 继续向下创建三个节点,包括姓名、年龄、介绍

              Element newStu_name = document.createElement("姓名");

              // 为该节点赋值

              newStu_name.setTextContent("小明");

              Element newStu_age = document.createElement("年龄");

              // 为该节点赋值

              newStu_age.setTextContent("23");

              Element newStu_introduce = document.createElement("介绍");

              // 为该节点赋值

              newStu_introduce.setTextContent("学习认真");

              // 将学生节点与姓名、年龄、介绍三个节点相关联

              newStu.appendChild(newStu_name);

              newStu.appendChild(newStu_age);

              newStu.appendChild(newStu_introduce);

              // 把新的学生节点添加到根元素

              document.getDocumentElement().appendChild(newStu);

              // 得到TransformerFactory

              TransformerFactory tff = TransformerFactory.newInstance();

              // 通过TransformerFactory得到一个转换器

              Transformer tf = tff.newTransformer();

              tf

                            .transform(new DOMSource(document), new StreamResult(

                                          "src/class.xml"));

       }

 

       public static void read(Document document) {

              // 通过getElementsByTagName()方法得出节点的名称

              NodeList nl = document.getElementsByTagName("学生");

              // 取出第一个学生的信息

              Element stu = (Element) nl.item(0);

              String stu_sex = stu.getAttribute("sex");

              System.out.println("学生的性别是" + stu_sex);

              Element name = (Element) stu.getElementsByTagName("姓名").item(0);

              System.out.println(name.getTextContent());

       }

 

       public static void list(Node node) {

              if (node.getNodeType() == node.ELEMENT_NODE) {

                     System.out.println("名字是" + node.getNodeName());

              }

              // 取出node的子节点

              NodeList nodelist = node.getChildNodes();

              // 通过递归调用来遍历xml文件

              for (int i = 0; i < nodelist.getLength(); i++) {

                     Node n = nodelist.item(i);

                     list(n);

              }

       }

}

  5.2.4JAXP练习:

       通过dom解析学生成绩,实现学生成绩管理系统。代码如下所示:

       student.xml

<?xml version="1.0" encoding="UTF-8"?>

<students>

       <student sid="001">

              <name>小明</name>

              <course>

                     <java>90</java>

                     <oracle>90</oracle>

                     <vb>89</vb>

              </course>

       </student>

       <student sid="002">

              <name>小李</name>

              <course>

                     <java>9</java>

                     <oracle>70</oracle>

                     <vb>8</vb>

              </course>

       </student>

       <student sid="003">

              <name>小韩</name>

              <course>

                     <java>90</java>

                     <oracle>70</oracle>

                     <vb>85</vb>

              </course>

       </student>

       <student sid="004">

              <name>小明名</name>

              <course>

                     <java>34</java>

                     <oracle>50</oracle>

                     <vb>58</vb>

              </course>

       </student>

       <student sid="005">

              <name>小红</name>

              <course>

                     <java>29</java>

                     <oracle>39</oracle>

                     <vb>88</vb>

              </course>

       </student>

</students>

     StudentGrade.java

package com.dom.exercise;

 

import java.util.Scanner;

 

public class StudentGrade {

       public static void main(String[] args) throws Exception {         

              while (true) {

                     show();

              }

       }

       public static void show() throws Exception {

              // 显示操作界面

              System.out.println("查询所有学生的成绩----view");

              System.out.println("退出系统----exit");

              // 获取用户的操作类型

              Scanner scanner = new Scanner(System.in);

              StudentService studentService = new StudentService();

              String operType = scanner.next();

              if (operType.equals("view")) {

                     // view操作

                     System.out.println("所有学生的成绩如下所示:");

            studentService.viewStudent();

              } else if (operType.equals("exit")) {

                     // exit操作

                     System.exit(1);

              }

       }

}

 Student.java

package com.dom.exercise;

 

class Student {

       private String sid;  //学生编号

       private String name; //学生姓名

       private int myjava;  //Java成绩

       private int myoracle;//Oracle成绩

       private int myvb;//VB成绩

    /*getter and setter*/

       public String getSid() {

              return sid;

       }

 

       public void setSid(String sid) {

              this.sid = sid;

       }

 

       public String getName() {

              return name;

       }

 

       public void setName(String name) {

              this.name = name;

       }

 

       public int getMyjava() {

              return myjava;

       }

 

       public void setMyjava(int myjava) {

              this.myjava = myjava;

       }

 

       public int getMyoracle() {

              return myoracle;

       }

 

       public void setMyoracle(int myoracle) {

              this.myoracle = myoracle;

       }

 

       public int getMyvb() {

              return myvb;

       }

 

       public void setMyvb(int myvb) {

              this.myvb = myvb;

       }

}

      StudentService.java

package com.dom.exercise;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.NodeList;

class StudentService {

       // 从指定的xml文件中得到信息

       public Document getDocument(String FullFilePath) throws Exception {

              // 1、得到DocumentBuilderFactory

              DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory

                            .newInstance();

              // 2、得到DocumentBuilder

              DocumentBuilder documentBuilder = documentBuilderFactory

                            .newDocumentBuilder();

              // 3、指定得到的文件

              return documentBuilder.parse(FullFilePath);

       }

       // 得到第一个元素的值

       public String getFirstElementTextVal(Element element, String name) {

              return ((Element) element.getElementsByTagName(name).item(0))

                            .getTextContent()

                            + "\t\t";

       }

       // 显示所有学生的成绩

       public void viewStudent() throws Exception {

              // 1、通过调用getDocument()方法显示学生信息

              NodeList nodeList = getDocument("src/com/dom/exercise/student.xml")

                            .getElementsByTagName("student");

              // 2、通过遍历nodeList格式化显示学生成绩

              for (int i = 0; i < nodeList.getLength(); i++) {

                     Element element = (Element) nodeList.item(i);

                     System.out.println("编号:" + element.getAttribute("sid") + "\t"

                                   + "名字:" + getFirstElementTextVal(element, "name") + "\t"

                                   + "Java成绩:" + getFirstElementTextVal(element, "java")

                                   + "\t" + "Oracle成绩:"

                                   + getFirstElementTextVal(element, "oracle") + "\t"

                                   + "VB成绩:" + getFirstElementTextVal(element, "vb") + "\t");

              }

       }

}

5.3SAX编程

5.3.1、概述:

l         在使用DOM解析xml文档时,需要读取整个xml文档,在内存中构建代表整个DOM树的Document对象,从而在对xml文档进行操作。此种情况下,如果xml文档特别大,就会消耗计算机的大量内存,严重的情况下可能会导致内存溢出。

l         sax解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才对文档进行操作。

l         面试题:

阅读以下代码,请问该段代码是否正确?

package com.hwb;

public class Test {

       public static void main(String[] args) {

              byte bytes[]=new byte[1024*1024*200];

              bytes[0]=0;

              System.out.println(bytes[0]);

       }

}

运行结果会出现如下错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

       at com.hwb.Test.main(Test.java:4)

默认情况下JVM的虚拟内存是64M,可以在“Properties for Xxx.java”中选择“Edit”按钮后选择“Argument”中“VM arguments”下添加“-Xmx200M”(200可以替换),即可指定jvm机启动的内存大小。

5.3.2、原理图:

5.3.3sax解析机制

    sax是一种推式机制,当创建一个sax解析器时解析器在发现xml文档中的内容是会把事件退给你,如何处理这些内容,由程序员自己决定。

    在基于sax的程序中,有五个最常用的sax事件:

    1startDocument()---->告诉我们解析器发现了文档的开始,并且解析器开始扫描文档;

    2endDocument()--->告诉我们解析器发现了文档尾;

    3startElement()--->告诉我们解析器发现了一个起始标签,该事件告诉我们元素的名称以及该元素所有的属性名和值;

    4character()--->告诉我们解析器发现了一些文本,将得到一个字符数组,该数组的偏移量和一个长度变量,有这三个变量便可以得到解析器所发现的文本;

    5endElement()--->告诉我们解析器发现了一个结束标签,该事件告诉元素的名称。

5.3.4sax解析

     sax采用事件处理的方式解析xml文件,利用sax解析xml文档,涉及两个部分:解析器和事件处理器:

l         解析器可以使用jaxpAPI创建,创建出sax解析器后就可以指定解析器去解析某个xml文档了;

l         解析器采用sax方式在解析某个xml文档时,它只要解析到xml文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器;

l         事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松的得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

 

5.3.5sax方式解析xml文档

l         使用SAXParseFactory创建sax解析工厂

SAXParseFactory spf = SAXParseFactory.newInstance();

l         通过sax解析工厂得到解析器对象

SAXParse sp = spf.newSAXParse();

l         将解析对象和事件处理器对象关联

sp.parse(“src/myClass.xml”,new MyHander());

5.3.6sax实例

     myClass.xml文件代码如下所示:

<?xml version="1.0" encoding ="utf-8"?>

<班级>

       <学生>

              <名字>周星驰</名字>

              <年龄>23</年龄>

              <介绍>学习刻苦</介绍>

       </学生>

       <学生>

              <名字>林青霞</名字>

               <年龄>32</年龄>

              <介绍>是一个好学生</介绍>

       </学生>

</班级>

   SaxXml类代码如下所示:

package com.hwb;

 

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

 

public class SaxXml {

       public static void main(String[] args) throws Exception {

              // 利用sax技术来解析xml文档,此例中解析myClass.xml文件

              // 使用SAXParseFactory创建sax解析工厂

              SAXParserFactory spf = SAXParserFactory.newInstance();

              // 通过sax解析工厂得到解析器对象

              SAXParser sp = spf.newSAXParser();

              // 将解析对象和事件处理器对象关联

              sp.parse("src/class.xml", new MyHander());

              System.out.println("*****************");

              sp.parse("src/class.xml", new Hander());

       }

}

MyHander类代码如下所示:

package com.hwb;

 

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

 

//定义事件处理类

class MyHander extends DefaultHandler {

       @Override

       //发现文档开始

       public void startDocument() throws SAXException {

              System.out.println("startDocument");

       }

 

       @Override

       //发现xml文件中的一个元素

       public void startElement(String uri, String localName, String qName,

                     Attributes attributes) throws SAXException {

              System.out.println("元素名称:" + qName);

       }

 

       @Override

       //发现xml文件中的一个文本

       public void characters(char[] ch, int start, int length)

                     throws SAXException {

              String con = new String(ch,start,length);

              if(!con.trim().equals("")){

                     System.out.println(con);

              }

       }

 

       @Override

       public void endElement(String uri, String localName, String qName)

                     throws SAXException {

              // TODO Auto-generated method stub

              super.endElement(uri, localName, qName);

       }

 

       @Override

       //发现文档结束

       public void endDocument() throws SAXException {

              System.out.println("endDocument");

       }

 

}

Hander类代码如下所示:

package com.hwb;

 

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

//只显示学生的姓名和年龄

class Hander extends DefaultHandler {

       private boolean isName = false;

       private boolean isAge = false;

       @Override

       //发现文档开始

       public void startDocument() throws SAXException {

              System.out.println("startDocument");

       }

 

       @Override

       //发现xml文件中的一个元素

       public void startElement(String uri, String localName, String qName,

                     Attributes attributes) throws SAXException {

              System.out.println("元素名称:" + qName);

       }

 

       @Override

       //发现xml文件中的一个文本

       public void characters(char[] ch, int start, int length)

                     throws SAXException {

              String con = new String(ch,start,length);

              if(!con.trim().equals("")&&(isAge||isName)){

                     System.out.println(con);

              }

              isName =false;

              isAge = false;

             

       }

 

       @Override

       public void endElement(String uri, String localName, String qName)

                     throws SAXException {

              if(qName.equals("名字")){

                     this.isName = true;

              }else if(qName.equals("年龄")){

                     this.isAge = true;

              }

       }

 

       @Override

       //发现文档结束

       public void endDocument() throws SAXException {

             

              System.out.println("endDocument");

       }

 

}

5.4DOM4J编程

5.4.1DOM4J解析XML文档

l         Dom4j是一个简单、灵活的开放源代码的库;与JDOM不同的是,dom4j使用接口和抽象基类,虽然dom4jAPI相对复杂一些,但它提供了比JDOM更好的灵活性;

l         Dom4j是一个非常优秀的Java xml API,具有性能优异、功能强大和极易使用的特点;现在很多软件采用的是Dom4j,比如说Hibernate

l         使用Dom4j开发,需要先下载dom4j相应的jar文件。

5.4.2Document对象

l         Dom4j中,获得Document对象的方式有三种:

1)读取xml文件,获得document对象

SAXReader saxReader = new SAXReader();

Docuement document = saxReader.read(new File(“文件地址以及文件名”));

2)解析xml形式的文本,得到document对象

String text =”<members></menbers>”;

Document document = DocumentHelper.parseText(text);

3)主动创建document对象

Document document = DocumentHelper.createDocument();

//创建根节点

Element root = document.addElement(“members”);

5.4.3、节点对象

l         1、获取文档的根节点

Element root = document.getRootElement();

l         2、取得某个节点的子节点

Element element = node.element(“书名”);

l         3、取得节点的文字

String text = node.getText();

l         4、取得某节点下所有名为“member”的子节点,并进行遍历

List nodes = rootEle.elements(“member”);

for(Iterator  it = nodes.iterator();it.hasNext();){

Element ele = (Element) it.next();

//do something

}

l         5、对某个节点的所有字典进行遍历

for(Iterator  it = nodes.iterator();it.hasNext();){

Element ele = (Element) it.next();

//do something

}

l         6、在某节点下添加子节点

Element ageElm = newMemberElm.addElement("age");

l         7、设置节点文字

element.setText(“2345”);

l         8、删除某节点

parentEle.remove(childEle);

l         9、添加一个CDATA节点

Element contentElm = infoElm.addElement(“content”);

contentElm.addCDATA(diary.getContent());

5.4.4、节点对象属性

l         1、取得某节点下的某属性

Element root = document.getRootElement();

Attribute attribute = root.attribute(“size”);

l         2、取得属性的文字

String text = attribute.getText();

l         3、删除某属性

Attribute attribute = root.attribute(“size”);

root.remove();

l         4、遍历某节点的所有属性

Element root = document.getRootElement();

for(Iterator it=root.attributeIterator;it.hasNext()){

Attribute attribute = attribute.getText();

String text = attribute.getText();

System.out.println(text);

}

l         5、设置某节点的属性和文字

newMemberEle.addAttribute(“name”,”sanjiang”);

l         6、设置属性的文字

Attribute attribute = root.attribute(“name”);

attribute.setText(“sanjiang”);

5.4.5Dom4j在指定位置插入节点

l         1、得到插入位置的节点列表(list);

l         2、调用list.add(index element),由index决定element的插入位置;

        Element元素可以通过DocumentHelper对象得到;示例代码如下:

Element element = DocumentHelper.createElement(“element”);

element.setText(“aaaa”);

List list = root.element(“”).elements();

list.add(1,aaa);

//更新document

l         3、将文档希尔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(new FileWriter("output.xml"),format);

writer.write(document);

writer.close();

出现乱码时使用以下代码:

new OutputStreamWriter(new FileOutputStream("src/.."),"utf-8");

   5.4.6Dom4j入门案例

          以下代码是allhero.xml文件,对其进行CRUD操作:

<?xml version="1.0" encoding="utf-8"?>

<水浒>

  <英雄>

    <名字别名="及时雨">宋江</名字

    <年龄>35</年龄

    <介绍>首领</介绍>

  </英雄

  <英雄>

    <名字别名="玉麒麟" >卢俊义</名字

    <年龄>25</年龄

    <介绍>二号首领</介绍>

  </英雄

  <英雄>

    <名字别名="行者">武松</名字

    <年龄>30</年龄

    <介绍>行者武松</介绍>

  </英雄>

</水浒>

     使用Dom4j解析代码如下所示:

 package com.dom4j.test;

 

import java.io.File;

import java.io.FileOutputStream;

import java.util.Iterator;

import java.util.List;

 

import org.dom4j.Document;

import org.dom4j.DocumentHelper;

import org.dom4j.Element;

import org.dom4j.io.OutputFormat;

import org.dom4j.io.SAXReader;

import org.dom4j.io.XMLWriter;

 

public class Dom4jTest {

       public static void main(String[] args) throws Exception {

              // 1、得到解析器

              SAXReader saxReader = new SAXReader();

              // 2、指定需要解析的xml文件

              Document document = saxReader.read(new File(

                            "src/com/dom4j/test/allhero.xml"));

              // 遍历文件

              list(document.getRootElement());

              // 读取第一个英雄的信息

              read(document);

              // xml文件中添加一个新的英雄

              add(document);

              // xml文件中删除某个英雄

              delete(document);

              // xml文件中的某个英雄后面添加新的英雄

              addByIndex(document);

       }

 

       @SuppressWarnings("unchecked")

       public static void addByIndex(Document document) throws Exception {

              // 首先创建一个新的英雄对象

              Element newHero = DocumentHelper.createElement("英雄");

              // 为对象添加属性

              newHero.setText("李逵");

              List<Element> allHeroes = document.getRootElement().elements("英雄");

              for (int i = 0; i < allHeroes.size(); i++) {

                     Element name = allHeroes.get(i).element("名字");

                     if (name.getText().equals("卢俊义")) {

                            System.out.println("i=" + i);

                            allHeroes.add(i + 1, newHero);

                            break;

                     }

              }

              // 设置输出的xml文件的格式,若不设置则会产生乱码

              OutputFormat outputFormat = OutputFormat.createPrettyPrint();

              outputFormat.setEncoding("UTF-8");

              // 更新xml文件

              XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(new File(

                            "src/com/dom4j/test/allhero.xml")), outputFormat);

              xmlWriter.write(document);

              xmlWriter.close();

       }

 

       public static void delete(Document document) throws Exception {

              // 找到该元素

              Element ele_hero = document.getRootElement().element("英雄")

                            .element("名字");

              // 删除该元素,通过得到该元素的父元素来删除

              ele_hero.getParent().remove(ele_hero);

              // 设置输出的xml文件的格式,若不设置则会产生乱码

              OutputFormat outputFormat = OutputFormat.createPrettyPrint();

              outputFormat.setEncoding("UTF-8");

              // 更新xml文件

              XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(new File(

                            "src/com/dom4j/test/allhero.xml")), outputFormat);

              xmlWriter.write(document);

              xmlWriter.close();

       }

 

       public static void add(Document document) throws Exception {

              // 首先创建一个新的英雄对象

              Element newHero = DocumentHelper.createElement("英雄");

              Element newHero_name = DocumentHelper.createElement("名字");

              Element newHero_age = DocumentHelper.createElement("年龄");

              Element newHero_intro = DocumentHelper.createElement("介绍");

              // 为对象添加属性

              newHero_name.setText("林冲");

              newHero_name.addAttribute("别名", "豹子头");

              // 关联子节点与父节点

              newHero.add(newHero_name);

              newHero.add(newHero_age);

              newHero.add(newHero_intro);

              // 把父节点添加到根节点下

              document.getRootElement().add(newHero);

              // 设置输出的xml文件的格式,若不设置则会产生乱码

              OutputFormat outputFormat = OutputFormat.createPrettyPrint();

              outputFormat.setEncoding("UTF-8");

              // 更新xml文件

              XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(new File(

                            "src/com/dom4j/test/allhero.xml")), outputFormat);

              xmlWriter.write(document);

              xmlWriter.close();

       }

 

       public static void read(Document document) {

              // 得到根元素

              Element element = document.getRootElement();

              // element.elements("英雄") :表示取出 root元素下的所有英雄元素

              // element.element("英雄") :表示取出 root元素下的第一个英雄元素

              // element.elements("英雄").get(0) :表示取出 root元素下的第一个学生元素

              Element hero = (Element) element.elements("英雄").get(0);

              Element hero_name = hero.element("名字");

              System.out.println(hero_name.getText() + "别名"

                            + hero_name.attributeValue("别名"));

       }

 

       // 遍历根元素

       @SuppressWarnings("unchecked")

       public static void list(Element element) {

              System.out.println(element.getName() + ":" + element.getTextTrim());

              Iterator iterator = element.elementIterator();

              while (iterator.hasNext()) {

                     Element ele = (Element) iterator.next();

                     list(ele);

              }

       }

}

5.4.7XPATH技术

          XPATH技术解决了按层取得元素的问题。

       具体案例详见其官方文档中案例。

6、疯狂XML书中重要案例

6.1DOM编程

6.1.1、使用dom解析xml文件 

book.xml代码如下所示:

<?xml version="1.0" encoding="GBK"?>

<书籍列表>

       <计算机书籍 ISBN="34553">

              <书名>疯狂Java讲义</书名>

              <价格>99.00</价格>

              <简要介绍>Java SE</简要介绍>

       </计算机书籍>

       <计算机书籍 ISBN="12345">

              <书名>疯狂Java WEB讲义</书名>

              <价格>89.00</价格>

              <简要介绍>Java WEB</简要介绍>

       </计算机书籍>

       <计算机书籍>

              <书名>疯狂XML讲义</书名>

              <价格>69.00</价格>

              <简要介绍>XML</简要介绍>

       </计算机书籍>

       <文学书籍>不能承受的生命之轻</文学书籍>

       <哲学书籍>

              <书名>乌合之众</书名>

              能提高人类对世界认识的书籍

       </哲学书籍>

</书籍列表>

DomParse.java代码如下所示:

/**

 *使用DOM模型解析xml文档内容

 */

package com.xml.dom;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

public class DomParse {

       public static void main(String[] args) throws Exception {

              // DOM解析器工厂

              DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

              factory.setIgnoringElementContentWhitespace(true);

              // 获取DOM解析器

              DocumentBuilder builder = factory.newDocumentBuilder();

              // 解析XML文档,并获取该XML文档对应的Document

              Document doc = builder.parse(new File("src/com/xml/dom/book.xml"));

              // 获取根节点的方法:getDocumentElement

              Element bookList = doc.getDocumentElement();

              // 获取根元素所包含的所有“计算机书籍”子元素,如果传入*做参数,可获取所有子元素

              NodeList nodeList = bookList.getElementsByTagName("计算机书籍");

              // 遍历每个子元素

              for (int i = 0; i < nodeList.getLength(); i++) {

                     System.out.println("" + i + "本计算机书籍");

                     Node comBook = nodeList.item(i);

                     //获取ISBN属性节点

                     Node isbnAttr = comBook.getAttributes().getNamedItem("ISBN");

                     if (isbnAttr != null) {

                            System.out.println("该图书的ISBN" + isbnAttr.getTextContent());

                     }

                     //获取comBook下的所有子元素

                     NodeList attList = comBook.getChildNodes();

                     //遍历每个子元素

                     for (int j = 0; j < attList.getLength(); j++) {

                            System.out.println(attList.item(j).getTextContent().trim());

                     }

              }

              // 获取根元素所包含的所有“文学书籍”子元素

              nodeList = bookList.getElementsByTagName("文学书籍");

              // 遍历每个子元素

              for (int i = 0; i < nodeList.getLength(); i++) {

                     System.out.println("" + i + "本文学书籍");

                     Node cultureBook = nodeList.item(i);

                     System.out.println(cultureBook.getTextContent());

              }

              // 获取根元素所包含的所有“哲学书籍”子元素

              nodeList = bookList.getElementsByTagName("哲学书籍");

              // 遍历每个子元素

              for (int i = 0; i < nodeList.getLength(); i++) {

                     System.out.println("" + i + "本哲学书籍");

                     Node philosophyBook = nodeList.item(i);

                     System.out.println(philosophyBook.getTextContent().trim());

                     System.out.println(philosophyBook.getFirstChild().getTextContent()

                                   .trim());

              }

       }

}

 6.1.2、使用dom创建xml文件 

   DomCreate.java代码如下所示:

/**

 *使用DOM模型创建xml文档

 */

package com.xml.dom;

import java.io.FileWriter;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Comment;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.ProcessingInstruction;

import org.w3c.dom.bootstrap.DOMImplementationRegistry;

import org.w3c.dom.ls.DOMImplementationLS;

import org.w3c.dom.ls.LSOutput;

import org.w3c.dom.ls.LSSerializer;

public class DomCreate {

       public static void main(String[] args) throws Exception {

              // DOM解析器工厂

              DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

              factory.setIgnoringElementContentWhitespace(true);

              // 获取DOM解析器

              DocumentBuilder builder = factory.newDocumentBuilder();

              // 创建一个新的Document对象

              Document doc = builder.newDocument();

              // 设置XML版本

              doc.setXmlVersion("1.0");

              // 创建处理指令

              ProcessingInstruction pi = doc.createProcessingInstruction("sju",

                            "href='www.sju.edu.cn'");

              // 添加处理指令

              doc.appendChild(pi);

              Comment comment = doc.createComment("根元素之前的注释");

              // 创建根元素

              Element root = doc.createElement("student");

              // 为根元素添加学号属性

              root.setAttribute("学号", "12010054052");

              // 创建name元素

              Element item = doc.createElement("name");

              // name元素增加文本子节点

              item.appendChild(doc.createTextNode("黄文伯"));

              // name元素添加到根元素之下

              root.appendChild(item);

              // 创建age元素

              item = doc.createElement("age");

              // age元素增加文本子节点

              item.appendChild(doc.createTextNode("24"));

              // age元素添加到根元素之下

              root.appendChild(item);

              // 创建high元素

              item = doc.createElement("high");

              // high元素增加文本子节点

              item.appendChild(doc.createTextNode("1.83"));

              // age元素添加到根元素之下

              root.appendChild(item);

              // 创建score元素

              item = doc.createElement("score");

              // 创建Java元素

              Element lesson = doc.createElement("Java");

              // Java元素添加文本子元素

              lesson.appendChild(doc.createTextNode("95"));

              // Java元素添加到score元素之下

              item.appendChild(lesson);

              // 创建Struts元素

              lesson = doc.createElement("Struts");

              // Struts元素添加文本子元素

              lesson.appendChild(doc.createTextNode("95"));

              // Struts元素添加到score元素之下

              item.appendChild(lesson);

              // 创建Hibernate元素

              lesson = doc.createElement("Hibernate");

              // Hibernate元素添加文本子元素

              lesson.appendChild(doc.createTextNode("85"));

              // Hibernate元素添加到score元素之下

              item.appendChild(lesson);

              // score元素添加到根元素下

              root.appendChild(item);

              // 为文档指定根元素

              doc.appendChild(root);

              // 获取DOMImplementationRegistry对象,它是获取DOMImplementation的工厂

              DOMImplementationRegistry registry = DOMImplementationRegistry

                            .newInstance();

              // 获取DOMImplementationLS对象

              DOMImplementationLS domImplLS = (DOMImplementationLS) registry

                            .getDOMImplementation("LS");

              // 获取LSSerializer对象,他是专门用于序列化DOM树的工具

              LSSerializer serializer = domImplLS.createLSSerializer();

              // 设置使用合理缩进使得xml文档更加美观

              serializer.getDomConfig().setParameter("format-pretty-print", true);

              LSOutput out = domImplLS.createLSOutput();

              // 指定输出文档编码所用的字符集

              out.setEncoding("GB2312");

              FileWriter stringOut = new FileWriter("src/com/xml/dom/test.xml");

              out.setCharacterStream(stringOut);

              // 执行序列化(将DOM树转换成XML文档)

              serializer.write(doc, out);

       }

}

结果生成create.xml文件,代码如下所示:

<?xml version="1.0" encoding="GB2312"?>

<student 学号="12010054052">

    <name>黄文伯</name>

    <age>24</age>

    <high>1.83</high>

    <score>

        <Java>95</Java>

        <Struts>95</Struts>

        <Hibernate>85</Hibernate>

    </score>

</student>

<?sju href='www.sju.edu.cn'?>

 6.1.3、使用dom更新 xml文件

   DomUpdate.java代码如下所示:

/**

 * 使用DOM修改XML文档

 */

package com.xml.dom;

import java.io.FileWriter;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.w3c.dom.bootstrap.DOMImplementationRegistry;

import org.w3c.dom.ls.DOMImplementationLS;

import org.w3c.dom.ls.LSOutput;

import org.w3c.dom.ls.LSSerializer;

 

public class DomUpdate {

       public static void main(String[] args) throws Exception {

              // DOM解析器工厂

              DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

              factory.setIgnoringElementContentWhitespace(true);

              // 获取DOM解析器

              DocumentBuilder builder = factory.newDocumentBuilder();

              // 创建一个新的Document对象

              Document doc = builder.parse("src/com/xml/dom/create.xml");

              // 获取文档中所有标签名为“name”的元素

              NodeList names = doc.getElementsByTagName("name");

              // 如果names节点列表不为null,且至少包含1个节点

              if (names != null && names.getLength() > 0) {

                     //获取第一个节点

                     Node name = names.item(0);

                     //修改节点数据

                     name.setTextContent("dirk");

              }

              // 获取DOMImplementationRegistry对象,它是获取DOMImplementation的工厂

              DOMImplementationRegistry registry = DOMImplementationRegistry

                            .newInstance();

              // 获取DOMImplementationLS对象

              DOMImplementationLS domImplLS = (DOMImplementationLS) registry

                            .getDOMImplementation("LS");

              // 获取LSSerializer对象,他是专门用于序列化DOM树的工具

              LSSerializer serializer = domImplLS.createLSSerializer();

              // 设置使用合理缩进使得xml文档更加美观

              serializer.getDomConfig().setParameter("format-pretty-print", true);

              LSOutput out = domImplLS.createLSOutput();

              // 指定输出文档编码所用的字符集

              out.setEncoding("GB2312");

              FileWriter stringOut = new FileWriter("src/com/xml/dom/update.xml");

              out.setCharacterStream(stringOut);

              // 执行序列化(将DOM树转换成XML文档)

              serializer.write(doc, out);

       }

}

结果生成update.xml文件代码如下所示:

<?xml version="1.0" encoding="GB2312"?>

<student 学号="12010054052">

    <name>dirk</name>

    <age>24</age>

    <high>1.83</high>

    <score>

        <Java>95</Java>

        <Struts>95</Struts>

        <Hibernate>85</Hibernate>

    </score>

</student>

<?sju href='www.sju.edu.cn'?>

6.2SAX编程

6.2.1、使用sax解析xml文件 

      book.xml文件以及其约束文档book.dtd代码如下所示:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE book SYSTEM "book.dtd"[

<!ELEMENT book (computer_book)*>

<!ELEMENT book_name (#PCDATA)>

<!ATTLIST computer_book intro_movie ENTITIES #IMPLIED>

]

<booklist>

       <computer_book intro-movie="movie">

              <book_name>疯狂Java</book_name>

              <book_price>99.00</book_price>

       </computer_book>

</booklist>

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT computer_book ((book_name,book_price))>

<!ELEMENT book_price (#PCDATA)>

<!--下面定义一个符号-->

<!NOTATION wmv SYSTEM "video/x-ms-wmv">

<!--只有外部实体才能是未解析实体-->

<!ENTITY movie SYSTEM "http://www.sju.edu.cn/test.wmv" NDATA wmv>

SAXParse类和MyHandler类代码如下所示:

/**

 * 使用XMLReaderSAXParser解析

 */

package com.xml.sax;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.XMLReader;

import org.xml.sax.helpers.XMLReaderFactory;

public class SaxParse {

       public static void main(String[] args) throws Exception{

              System.out.println("--使用XMLReader解析--");

              //创建XMLReader解析器

              XMLReader reader = XMLReaderFactory.createXMLReader();

              //注册ContentHandler解析器

              reader.setContentHandler(new MyHandler());

              //注册DTDHandler监听器

              reader.setDTDHandler(new MyHandler());

              reader.parse("src/com/xml/sax/book.xml");

              System.out.println("--使用SAXParser解析--");

              //创建SAX解析器工厂

              SAXParserFactory factory = SAXParserFactory.newInstance();

              //创建SAX解析器工厂

              SAXParser parser = factory.newSAXParser();

              //开始解析XML文档

              parser.parse("src/com/xml/sax/book.xml", new MyHandler());

       }

}

package com.xml.sax;

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

public class MyHandler extends DefaultHandler {

       // 定义一个成员变量来保存当前正在处理的Tag

       private String currentTag;

       // 每当处理文本数据是将触发该方法

       @Override

       public void characters(char[] ch, int start, int length)

                     throws SAXException {

              String content = new String(ch, start, length);

              if (content.trim().length() > 0) {

                     System.out.println("<" + currentTag + ">元素的值是:" + content.trim());

              }

 

       }

       // 处理文档结束时触发该方法

       @Override

       public void endDocument() throws SAXException {

              System.out.println("解析文档结束!");

       }

       // 处理文档结束时触发该方法

       @Override

       public void endElement(String uri, String localName, String qName)

                     throws SAXException {

              System.out.println("处理元素结束:" + qName);

       }

       // 处理元素里命名空间属性结束是触发该方法

       @Override

       public void endPrefixMapping(String prefix) throws SAXException {

              System.out.println("<" + currentTag + ">元素的命名空间属性的前缀:" + prefix);

       }

       // 处理元素内容中可忽略的空白是触发该方法

       @Override

       public void ignorableWhitespace(char[] ch, int start, int length)

                     throws SAXException {

 

       }

       // 解析处理指令是触发该方法

       @Override

       public void processingInstruction(String target, String data)

                     throws SAXException {

              System.out.println("当前处理的指令是:" + target);

              System.out.println("处理指令数据是:" + data);

       }

       // 跳过实体时触发该方法

       @Override

       public void skippedEntity(String name) throws SAXException {

              System.out.println("SAX解析器跳过的实体名是:" + name);

       }

       // 开始解析文档时触发该方法

       @Override

       public void startDocument() throws SAXException {

              System.out.println("解析文档开始!");

       }

       @Override

       public void startElement(String uri, String localName, String qName,

                     Attributes attributes) throws SAXException {

              System.out.println("开始处理元素:" + qName);

              currentTag = qName;

              // attributes代表该元素包含的所有属性

              int len = attributes.getLength();

              if (len > 0) {

                     System.out.println("<" + currentTag + ">元素的属性如下:");

                     for (int i = 0; i < len; i++) {

                            System.out.println(attributes.getQName(i) + "--->"

                                          + attributes.getValue(i));

                     }

              }

       }

       // 开始处理元素里命名空间属性是触发该方法

       @Override

       public void startPrefixMapping(String prefix, String uri)

                     throws SAXException {

              System.out.println("<" + currentTag + ">元素的命名空间属性的前缀:" + prefix);

              System.out.println("<" + currentTag + ">元素的命名空间属性的URI为:" + uri);

       }

       // 当遇到DTD中的符号定义时触发该方法

       @Override

       public void notationDecl(String name, String publicId, String systemId)

                     throws SAXException {

              System.out.println("当前符号的名字是:" + name);

              System.out.println("当前符号的PUBLIC ID是:" + publicId);

              System.out.println("当前符号的SYSTEM ID是:" + systemId);

       }

       @Override

       public void unparsedEntityDecl(String name, String publicId,

                     String systemId, String notationName) throws SAXException {

              System.out.println("当前未解析实体的名字是:" + name);

              System.out.println("当前未解析实体的PUBLIC ID是:" + publicId);

              System.out.println("当前未解析实体的SYSTEM ID是:" + systemId);

              System.out.println("当前未解析实体实体关联符号名是:" + notationName);

       }

}

你可能感兴趣的:(计算机,一般搜索不到的东西,网上转载的额)