JavaEE 自学笔记 --XML 解析

JAXP DOM 解析

JAXP SAX 解析

XML PULL 进行STAX 解析


XML 技术主要企业应用

1、存储和传输数据

2、作为框架的配置文件


使用xml存储和传输数据

1、通过程序生成xml

2、读取xml中数据---- xml 解析


什么是DOMSAX

DOM Document ObjectModel ----- 文档对象模型

DOM思想:将整个xml 加载内存中,形成文档对象,所有对xml操作都对内存中文档对象进行

DOM 是官方xml解析标准

* 所有开发语言都支持的


JavaJavaScript都支持DOM


SAX Simple API for XML----- XML 简单API

程序员为什么发明sax解析方式??xml 文档非常大,不可能将xml所有数据加载到内存

SAX 思想:一边解析,一边处理,一边释放内存资源---- 不允许在内存中保留大规模xml数据


StAX The Stream API forXML ----- XML API

STAX 是一种拉模式 xml解析方式,SAX是一种推模式 XML解析方式


push模式:由服务器为主导,向客户端主动发送数据

pull模式:由客户端为主导,主动向服务器申请数据


程序员在实际开发中,使用已经开发好工具包----- JAXP DOM4jXMLPULL


解析方式 解析开发包关系?

解析方式是解析xml思想,没有具体代码,解析开发包是解析xml思想具体代码实现


JAXP sun官方推出实现技术同时支持 DOMSAX STAX

DOM4j 是开源社区开源框架 支持 DOM解析方式

XML PULL Android移动设备内置xml解析技术支持 STAX解析方式



SAXSTAX读取xml数据时,如果读取到内存数据不释放----- 内存中将存在整个xml文档数据(类似DOM 支持修改和回写)


DOMSAXSTAX在实际开发中选择?

javaee日常开发中---- 优先使用DOM(编程简单)

xml文档数据非常多,不可能使用DOM---造成内存溢出 ------ 优先使用STAX

移动开发使用 STAX---- Android XML PULL


JAXP 开发进行 xml解析

javax.xml.parsers 存放DOM SAX 解析器

javax.xml.stream 存放STAX 解析相关类

org.w3c.dom 存放DOM解析时数据节点类

org.xml.sax存放SAX解析相关工具类


DOM 解析快速入门

1、创建xml 文档books.xml

在企业实际开发中,为了简化xml生成和解析---- xml 数据文件通常不使用约束的

2、使用DOM解析xml

将整个xml文档加载到内存中 工厂--- 解析器--- 解析加载

3Document通过getElementsByTagName 获得节点集合 NodeList

通过NodeList 提供getLength item 遍历节点集合


遍历ArrayList

for (inti=0;i<arraylist.size();i++){

arraylist.get(i);

}


遍历NodeList

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

nodelist.item(i); ----- 将遍历每个节点转换子接口类型

}


什么是Node? 对于xml来说,xml所有数据都是node节点(元素节点、属性节点、文本节点、注释节点、CDATA节点、文档节点)

Element Attr TextComment CDATASection Document ----- 都是Node 子接口


node有三个通用API

getNodeName():返回节点的名称

getNodeType():返回节点的类型

getNodeValue():返回节点的值 ---- 所有元素节点value都是null


----------------------------------------------------------------------------------------

DOM 编程思路小结

1、装载XML文档---- Document

2Document获得指定元素----- getElementsByTagName (返回NodeList

3、遍历NodeList获得每个 Node

4、将每个Node强制转换Element

5、通过元素节点API操作属性和文本内容

getAttribute 获得属性值

getTextContent获得元素内部文本内容



先用全局查找锁定范围,再用相对关系查找得到需要数据


getElementById 方法必须用于带有约束xml文档中!!!!!!!


所以开发语言默认支持DTD,当使用Schema时,单独编程导入schema


XML DOM 增加、修改 删除操作 ------操作内存中文档对象


XML的回写


XML元素添加 1、创建节点元素2、将节点元素加入指定位置


XML元素修改 查询到指定元素1、修改属性setAttribute 2、修改元素文本内容setTextContent


XML元素删除:删除节点.getParentNode().removeChild(删除节点)


-------------------------------------------------------------------------------------------------

SAX STAX 都是基于事件驱动 -----SAX推模式STAX拉模式

SAX常用事件

startDocument() ----文档开始事件

startElemen() ----元素开始事件

characters() ----文本元素事件

endElement() ----元素结束事件

endDocument() -----文档结束事件


为什么说SAX是推模式解析?解析器控制xml文件解析,由解析器调用相应事件方法


startElemen()endElement() 获得开始和结束元素名称

characters()获得读取到文本内容

startElemen()读取属性值



STAX 拉模式xml解析方式----- 客户端程序,自己控制xml事件,主动调用相应事件方法


当使用XMLPULL 如果使用Android系统,系统内置无需下载任何开发包,如果想JavaSEJavaEE 使用pull解析技术下载单独pull 开发工具包


xpp3 ----- XML PullParser 3 pullAPI 代码实现


使用pull解析器

1、去网站上下载 pull解析器实现xpp3 (Android 内置)

2、将xpp3-1.1.3.4.C.jar 导入java工程

导入jar位于 当前工程内部, 在工程内新建lib ,将jar复制过来 pull解析器jar 添加buildpath


jar 包就是.class文件集合压缩包(采用zip格式压缩)


Pull解析器使用 stax解析方式---- 拉模式解析

Pull采用将xml文档传递解析器,手动通过next触发文档解析事件,在客户端代码中获取当前事件,从而调用相应事件处理方法


3、创建pull解析器

4、将xml文档内容传递pull 解析器


为什么STAX 解析方式效率 好于SAX

1SAX无选择性的,所有事件都会处理解析方式,Stax 由用户控制需要处理事件类型

2、在使用Stax进行数据解析时,随时终止解析


Pull 解析器生成 xml文档功能---- 通过XmlSerializer 生成xml 文档

解析xml文档开始、元素开始、文本元素、元素结束、文档结束

生成xml:生成文档声明(文档开始),元素开始、文本内容、元素结束、文档结束

1、生成简单xml

2、通过对象数据生成xml

3、通过对象List数据生成xml


在程序中抽取两个方法----- 1. xml --- List对象 2. List对象生成xml


对内存中List进行CURD操作



作业:

1、整理DOM SAXSTAX原理和区别

2、编写商品xml文件--- 通过JAXPDOM 完成CURD操作

3、编写SAX运行案例----- 了解

4、编写商品XML文件--- 通过Pull解析器完成CURD操作 ---- 重点xml2List list2xml 两个方法



//需要解析的xml文件

<?xmlversion="1.0" encoding="UTF-8"?>

<!DOCTYPEbooks [

<!ELEMENTbooks (book+) >

<!ELEMENTbook (name,price) >

<!ELEMENTname (#PCDATA) >

<!ELEMENTprice (#PCDATA) >

<!ATTLISTbook

id ID #REQUIRED

>

]>

<books>

<bookid="b001">

<name>java编程基础</name>

<price>80</price>

</book>

<bookid="b002">

<name>java高级应用</name>

<price>100</price>

</book>

<bookid="boo3">

<name>编程高手秘笈</name>

<price>200</price>

</book>

</books>

//Pull 解析代码

import org.junit.Test;

importorg.xmlpull.v1.XmlPullParser;

importorg.xmlpull.v1.XmlPullParserFactory;

public class PullTest {

@Test

// 通过pull 解析技术查看 "编程高手秘笈"价格

public void demo2()throws Exception {

// 1. 创建pull 解析器

XmlPullParserFactoryfactory = XmlPullParserFactory.newInstance();

XmlPullParser parser= factory.newPullParser();

// 2. xml文档传递解析器

parser.setInput(newFileInputStream("books.xml"), "utf-8");


// 通过循环驱动事件解析

int event;


// 查找name标识位

boolean isFound =false;

while ((event =parser.getEventType()) != XmlPullParser.END_DOCUMENT) {

// 获得开始元素 name

if (event ==XmlPullParser.START_TAG

&&parser.getName().equals("name")) {

// 获得元素后面文本

String bookname =parser.nextText();

if(bookname.equals("编程高手秘笈")){

isFound = true;

// 这本书就是我找到

// parser.next();

//System.out.println(parser.getEventType());

// parser.next();// price 开始

//System.out.println(parser.getEventType());

// String money =parser.nextText();

//System.out.println(money);

}

}


if (event ==XmlPullParser.START_TAG

&&parser.getName().equals("price") && isFound) {

System.out.println(parser.nextText());

break;

}


parser.next();

}

}


@Test

public void demo1()throws Exception {

// 1、创建xml pull 解析器

// 工厂

XmlPullParserFactoryxmlPullParserFactory = XmlPullParserFactory

.newInstance();


// 通过工厂获得解析器

XmlPullParser parser= xmlPullParserFactory.newPullParser();


// 2、将xml 文件传递 解析器

parser.setInput(newFileInputStream("books.xml"), "utf-8");


// pull 解析器用得是拉模式 数据解析

int event;


while ((event =parser.getEventType()) != XmlPullParser.END_DOCUMENT) {

// 打印哪个元素开始了---- 判断当前事件 元素开始事件

if (event ==XmlPullParser.START_TAG) {

// 所有数据从解析器 获得

System.out.println(parser.getName()+ "元素开始了...");

}


// 打印哪个 元素结束了

if (event ==XmlPullParser.END_TAG) {

System.out.println(parser.getName()+ "元素结束了...");

}


// 处理下一个事件

parser.next();

}


// // 获得当前事件类型

// int event =parser.getEventType();

//

//System.out.println(event);

//

// parser.next(); //解析器解析下一个事件

//

// int event2 =parser.getEventType();

//

//System.out.println(event2);

//

// parser.next();

//

// int event3 =parser.getEventType();

//

//System.out.println(event3);


}

}


//生成pull笔记

import org.junit.Test;

importorg.xmlpull.v1.XmlPullParserFactory;

importorg.xmlpull.v1.XmlSerializer;


/**

* 生成xml

*

*/

public classSerializerTest {

@Test

// 根据List<Company> 生成xml

public void demo3()throws Exception {

List<Company>companies = new ArrayList<Company>();


Company company = newCompany();

company.setName("Google");

company.setPnum(200);

company.setAddress("软件园!");


Company company2 =new Company();

company2.setName("CSDN");

company2.setPnum(1000);

company2.setAddress("软件园 ");


companies.add(company);

companies.add(company2);


// 序列化对象

XmlSerializerserializer = XmlPullParserFactory.newInstance()

.newSerializer();


// 设置输出文件

serializer.setOutput(newFileOutputStream("company.xml"), "utf-8");


serializer.startDocument("utf-8",true);


serializer.startTag(null,"companies");


// 遍历list集合

for (Company c :companies) {

serializer.startTag(null,"company");


serializer.startTag(null,"name");

serializer.text(c.getName());

serializer.endTag(null,"name");


serializer.startTag(null,"pnum");

serializer.text(c.getPnum()+ "");

serializer.endTag(null,"pnum");


serializer.startTag(null,"address");

serializer.text(c.getAddress());

serializer.endTag(null,"address");


serializer.endTag(null,"company");

}


serializer.endTag(null,"companies");


serializer.endDocument();


}


@Test

// 根据company对象数据生成xml

public void demo2()throws Exception {

Company company = newCompany();

company.setName("我的百度");

company.setPnum(200);

company.setAddress("西二旗软件园!");


/*

* <company>

*

* <name>我的百度</name>

*

* <pnum>200</pnum>

*

*<address>西二旗软件园</address>

*

* </company>

*/


// 获得序列化对象

XmlSerializerserializer = XmlPullParserFactory.newInstance()

.newSerializer();


// 传递输出目标文件 给序列化对象

serializer.setOutput(newFileOutputStream("company.xml"), "utf-8");


serializer.startDocument("utf-8",true);


serializer.startTag(null,"company");


serializer.startTag(null,"name");

serializer.text(company.getName());

serializer.endTag(null,"name");


serializer.startTag(null,"pnum");

serializer.text(company.getPnum()+ "");

serializer.endTag(null,"pnum");


serializer.startTag(null,"address");

serializer.text(company.getAddress());

serializer.endTag(null,"address");


serializer.endTag(null,"company");


serializer.endDocument();

}


@Test

public void demo1()throws Exception {

// 获得XmlSerializer对象

XmlPullParserFactoryfactory = XmlPullParserFactory.newInstance();

XmlSerializerserializer = factory.newSerializer();


// 设置序列化输出文档

serializer.setOutput(newFileOutputStream("company.xml"), "utf-8");


// 文档开始

serializer.startDocument("utf-8",true);


// 元素开始

serializer.startTag(null,"company"); // 没有命名空间"" 或者null


// 文本元素

serializer.text("我的百度");


// 元素结束

serializer.endTag(null,"company");


// 文档结束

serializer.endDocument();


/*

* <?xmlversion="1.0" encoding="UTF-8" standalone="yes"?>

*

* <company>

*

* 我的百度

*

* </company>

*/

}

}


创建的xml文件

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

<companies>

<company>

<name>我的百度</name>

<pnum>200</pnum>

<address>西二旗软件园!</address>

</company>

<company>

<name>CSDN</name>

<pnum>1000</pnum>

<address>软件园 </address>

</company>

</companies>


//增删改查xml内容

import org.junit.Test;

importorg.xmlpull.v1.XmlPullParser;

importorg.xmlpull.v1.XmlPullParserFactory;


importcn.itcast.domain.Company;


/**

* 完成pull解析器CURD操作

*

*/

public class PullCURD {

@Test

// xml中数据---- List集合对象

public void demo1()throws Exception {

List<Company>companies = new ArrayList<Company>();

Company company =null;


// 获得解析器

XmlPullParserFactoryfactory = XmlPullParserFactory.newInstance();

XmlPullParser parser= factory.newPullParser();


// 向解析器传入xml文件

parser.setInput(newFileInputStream("company.xml"), "utf-8");


// 遍历解析

int event;

while ((event =parser.getEventType()) != XmlPullParser.END_DOCUMENT) {


if (event ==XmlPullParser.START_TAG

&&parser.getName().equals("company")) {

// company 开始创建 company对象

company = newCompany();

}


if (event ==XmlPullParser.START_TAG

&&parser.getName().equals("name")) {

// name 元素开始-- 封装name属性

company.setName(parser.nextText());

}


if (event ==XmlPullParser.START_TAG

&&parser.getName().equals("pnum")) {

company.setPnum(Integer.parseInt(parser.nextText()));

}


if (event ==XmlPullParser.START_TAG

&&parser.getName().equals("address")) {

company.setAddress(parser.nextText());

}


if (event ==XmlPullParser.END_TAG

&&parser.getName().equals("company")) {

// company 结束

companies.add(company);

}


parser.next();

}


for (Company c :companies) {

System.out.println(c.getName());

System.out.println(c.getPnum());

System.out.println(c.getAddress());

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

}


}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值