xml视频笔记

前端之家收集整理的这篇文章主要介绍了xml视频笔记前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1、xml发展历史

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

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

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

1993html(www)

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

1标记不能自定义


@H_301_56@

<html>

       <body>

              <table>

                     <td>123</td>

              </table>

       </body>

</html>

2html本身缺少一些含义

@H_301_56@

<html>

<body>

<h1>水浒英雄</h1>

<table>

<tr>

<td>宋江</td>

</tr>

</table>

</body>

</html>

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

2、为什么需要学习xml

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

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

@H_301_56@

2)可以用做配置文件

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

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

3、xml语法

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

@H_301_56@

<?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、文档声明

@H_301_56@

<?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、转义字符

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

@H_301_56@ @H_301_56@ @H_301_56@ @H_301_56@ @H_301_56@ @H_301_56@

转义符

符号

&lt;

<

&gt;

>

&amp;

&

&quot;

&apos;

3.6、处理指令(processing instruction

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

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

@H_301_56@

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

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

@H_301_56@

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代码如下:

@H_301_56@

<?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之间的关系如下图所示:

@H_301_56@

b、基本语法:

@H_301_56@

<!ELEMENT元素名类型>

c快速入门案例:

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

@H_301_56@ @H_301_56@

<?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工具进行验证;

主要步骤如下:

@H_301_56@

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

2、开启xml校验

3、装载xml文档

4获取错误信息

实现代码如下所示:

@H_301_56@

<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文档

@H_301_56@

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

示例:

@H_301_56@

<?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文档

@H_301_56@

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

示例见入门案例。

内外部DTD文档结合

@H_301_56@

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

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

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

@H_301_56@

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

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

@H_301_56@

<!DOCTYPE文档根结点PUBLIC “DTD名称” “DTD文件URL”>

示例:

@H_301_56@

<!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语法

@H_301_56@

<!ELEMENT NAME CONTENT>

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

CONTENT包括以下三种:

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

示例:

@H_301_56@

<!ELEMENTEMPTY>

<家庭>

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

</家庭>

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

示例:

@H_301_56@

<!ELEMENTANY>

<家庭>

<>皮诺曹</>

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

</家庭>

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

@H_301_56@

<!ELEMENT(#PCDATA)>

<家庭>

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

</家庭>

组合类型如下所示:

@H_301_56@

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

<家庭>

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

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

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

</家庭>

修饰符如下所示:

@H_301_56@ @H_301_56@ @H_301_56@ @H_301_56@ @H_301_56@ @H_301_56@ @H_301_56@

编号

符号

用途

示例

示例说明

1

( )

用来给元素分组

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

分成三组

2

|

在列中的对象中选择一个

(男人|女人)

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

3

+

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

(成员+)

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

4

*

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

(爱好*)

爱好可以出现零次到多次

5

?

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

(菜鸟?)

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

6

,

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

(西瓜,苹果,香蕉)

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

4.3属性

a、语法:

@H_301_56@

<!ATTLIST元素名称

属性名称类型属性特点

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

>

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

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

b属性类型:

lCDATA属性值可以使任何字符(包括数字和中文

@H_301_56@

<!ATTLIST木偶

姓名CDATA #required

>

<木偶姓名="dirk">

<木偶姓名="德克">

<木偶姓名="dirk41">

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

@H_301_56@

<!ELEMENT公司职员ANY>

<!ATTLIST公司职员

编号ID #required

姓名CDATA #required

>

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

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

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

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

@H_301_56@

<!ELEMENT家庭(+)>

<!ELEMENTEMPTY>

<!ATTLIST

relID ID #required

parentID IDREFS #IMPLIED

name CDATA #REUIRED

>

<家庭>

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

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

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

</家庭>

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

@H_301_56@

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

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

c属性的特点:

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

语法:

@H_301_56@

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

示例:

@H_301_56@

<!ATTLIST person number CDATA #required>

<person number="5678"/>

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

语法:

@H_301_56@

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

示例:

@H_301_56@

<!ATTLIST contact fax CDATA #IMPLIED>

<contact fax="555-667788">

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

语法:

@H_301_56@

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

示例:

@H_301_56@

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

<sender company="Microsofr"/>

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

语法:

@H_301_56@

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

示例:

@H_301_56@

<!ATTLIST payment type CDATA "check">

<payment type="check"/>

d、实体:

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

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

语法:

@H_301_56@

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

引用方式:

@H_301_56@

&实体名称;

示例:

@H_301_56@

<!ENTITY copyright "I am a coder">

&copyright;

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

语法:

@H_301_56@

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

引用方式:

@H_301_56@

%实体名称;

示例:

@H_301_56@ @H_301_56@

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

@H_301_56@ @H_301_56@

!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

@H_301_56@ @H_301_56@

<!DOCTYPE CATALOG [

<!ENTITY AUTHOR "John Doe">

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

<!ENTITY EMAIL "jd@jd-tools.com">

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

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

lxml 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文件中的内容

@H_301_56@

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

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

</itcast>

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

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

快速入门案例:

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

@H_301_56@ @H_301_56@

<?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基本格式:

@H_301_56@

xmlns=”URI”

l举例:

@H_301_56@

<?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介绍

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

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

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

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

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

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

5.2DOM编程

lDOM模型就是Document Object Model

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

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

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

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

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

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

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

xml DOM的解析图如下所示:

@H_301_56@

5.2.1Node对象

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

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

5.2.2、更新XML文档

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

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

lTransformer对象通过TransformerFactory获得。

5.2.3JAXP实例:

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

@H_301_56@

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

<班级>

<学生>

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

<年龄>23</年龄>

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

</学生>

<学生>

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

<年龄>45</年龄>

<介绍>认真</介绍>

</学生>

</班级>

DomXml1.java代码如下所示:

@H_301_56@

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

@H_301_56@

<?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

@H_301_56@

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

@H_301_56@

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

@H_301_56@

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文档特别大,就会消耗计算机的大量内存,严重的情况下可能会导致内存溢出。

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

l面试题:

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

@H_301_56@

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]);

}

}

运行结果会出现如下错误

@H_301_56@

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、原理图:

@H_301_56@

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文件代码如下所示:

@H_301_56@

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

<班级>

<学生>

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

<年龄>23</年龄>

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

</学生>

<学生>

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

<年龄>32</年龄>

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

</学生>

</班级>

SaxXml代码如下所示:

@H_301_56@

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代码如下所示:

@H_301_56@

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 qName)

throws SAXException {

// TODO Auto-generated method stub

super.endElement(uri,localName,qName);

}

@Override

//发现文档结束

public void endDocument() throws SAXException {

System.out.println("endDocument");

}

}

Hander代码如下所示:

@H_301_56@

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,length);

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

System.out.println(con);

}

isName =false;

isAge = false;

}

@Override

public void endElement(String uri,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文档

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

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

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

5.4.2Document对象

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

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

@H_301_56@

SAXReader saxReader = new SAXReader();

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

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

@H_301_56@

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

Document document = DocumentHelper.parseText(text);

3)主动创建document对象

@H_301_56@

Document document = DocumentHelper.createDocument();

//创建根节点

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

5.4.3、节点对象

l1获取文档的根节点

@H_301_56@

Element root = document.getRootElement();

l2、取得某个节点的子节点

@H_301_56@

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

l3、取得节点的文字

@H_301_56@

String text = node.getText();

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

@H_301_56@

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

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

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

//do something

}

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

@H_301_56@

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

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

//do something

}

l6、在某节点下添加子节点

@H_301_56@

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

l7、设置节点文字

@H_301_56@

element.setText(“2345”);

l8删除某节点

@H_301_56@

parentEle.remove(childEle);

l9添加一个CDATA节点

@H_301_56@

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

contentElm.addCDATA(diary.getContent());

5.4.4、节点对象属性

l1、取得某节点下的某属性

@H_301_56@

Element root = document.getRootElement();

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

l2、取得属性文字

@H_301_56@

String text = attribute.getText();

l3删除属性

@H_301_56@

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

root.remove();

l4、遍历某节点的所有属性

@H_301_56@

Element root = document.getRootElement();

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

Attribute attribute = attribute.getText();

String text = attribute.getText();

System.out.println(text);

}

l5、设置某节点的属性文字

@H_301_56@

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

l6、设置属性文字

@H_301_56@

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

attribute.setText(“sanjiang”);

5.4.5Dom4j在指定位置插入节点

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

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

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

@H_301_56@

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

element.setText(“aaaa”);

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

list.add(1,aaa);

//更新document

l3、将文档希尔xml文件

1)文档中全为英文,不设置编码,直接写入的形式

@H_301_56@

XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));

writer.write(document);

writer.close();

2)文档中含有中问,设置编码格式写入的形式

@H_301_56@

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操作:

@H_301_56@

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

<水浒>

<英雄>

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

<年龄>35</年龄>

<介绍>首领</介绍>

</英雄>

<英雄>

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

<年龄>25</年龄>

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

</英雄>

<英雄>

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

<年龄>30</年龄>

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

</英雄>

</水浒>

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

@H_301_56@

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代码如下所示:

@H_301_56@

<?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代码如下所示:

@H_301_56@

/**

*使用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代码如下所示:

@H_301_56@

/**

*使用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文件代码如下所示:

@H_301_56@

<?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代码如下所示:

@H_301_56@

/**

*使用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文件代码如下所示:

@H_301_56@

<?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代码如下所示:

@H_301_56@ @H_301_56@

<?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代码如下所示:

@H_301_56@ @H_301_56@

/**

*使用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 length)

throws SAXException {

String content = new String(ch,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 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 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,

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 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);

}

}

猜你在找的XML相关文章