dom4j和sax解析XML文档以及简单工厂模式介绍

来源:互联网 发布:微信一键加人软件 编辑:程序博客网 时间:2024/06/09 23:27

XML编程(C.R.U.D)

XML解析技术概述

XML解析方式主要分为两种:domsax

dom:document object model(即文档对象模型)

sax:simple API for xml(见名知意)

XML解析器Crimson(SUN)Xerces(IBM->APACHE)Aelfred2(DOM4J开源组织)

XML解析技术API/开发包(程序员主要关心这个API.....{[(-_-)(-_-)]}zzz

Jaxp(SUN/dom/sax)Jdomdom4j

DOM4J解析XML文档


 

Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4jAPI相对要复杂一些,但它提供了比JDOM更好的灵活性。

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

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

查看Dom4j文档

 

dom4j解析器

  1CRUD的含义:Create Read Update Delete增删查改

  2XML解析器有二类,分别是DOMSAX

a)DOM一次性将整个XML文件读到内存,形成一个倒状的树形结构

    b)SAX多次将整个XML文件读到内存

    c)Document对象代表XML文件在内存中的映像

 

 

使用dom4j解析XML文件

//创建dom4j解析器

SAXReader saxReader = new SAXReader();

//加载需要解析的xml文件

Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));

//取得根元素

Element rootElement = document.getRootElement();

//显示根元素的名称

System.out.println(rootElement.getName());//车辆清单

//取得根元素下的子元素

List<Element> elementList = rootElement.elements();

System.out.println("共有" +elementList.size()+"辆车");

for(Element e : elementList){

System.out.println("车牌:" +e.elementText("车牌"));

System.out.println("产地:" +e.elementText("产地"));

System.out.println("出产时间:" +e.element("车牌").attributeValue("出产时间"));

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

}

输出结果:

车辆清单

共有2辆车

车牌:奥迪

产地:北京

出产时间:2010年

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

车牌:本田

产地:广州

出产时间:2011年

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

//使用dom4j操作xml文件的cud 

获得document对象

private Document getDocument()throws Exception {

SAXReader saxReader = new SAXReader();

Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));

return document;

}

//将内存中的xml文件写到硬盘中

private void write2xml(Documentdocument) throws Exception {

OutputFormat format = OutputFormat.createPrettyPrint();

OutputStream os =new FileOutputStream("src/cn/itcast/xml/dom4j/car.xml");

XMLWriter xmlWriter = new XMLWriter(os,format);

xmlWriter.write(document);

xmlWriter.close();

}

@Test

public void create()throws Exception{

Document document = getDocument();

Element rootElement = document.getRootElement();

//取得第一辆汽车

Element firstCarElement = (Element) rootElement.elements().get(0);

//添加新元素"单价",并设置文本为30

firstCarElement.addElement("单价").setText("40");

//将内存中的xml文件写到硬盘中

write2xml(document);

}

 

 

@Test

public void update()throws Exception{

Document document = getDocument();

Element rootElement = document.getRootElement();

Element firstCarElement = (Element) rootElement.elements().get(0);

firstCarElement.element("单价").setText("60");

write2xml(document);

}

 

@Test

public void delete()throws Exception{

Document document = getDocument();

Element rootElement = document.getRootElement();

Element firstCarElement = (Element) rootElement.elements().get(0);

Element firstCarPriceElement = firstCarElement.element("单价");

firstCarElement.remove(firstCarPriceElement);

//firstCarPriceElement.getParent().remove(firstCarPriceElement);

write2xml(document);

}

 

需求:从src/cn/itcast/xml/dom4j/car.xml解析数据并封装到JavaBean中,并按汽车单价进行排序

package cn.itcast.xml.dom4j;

 

import java.io.File;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import org.dom4j.Document;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;

 

public class Demo3 {

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

SAXReader saxReader = new SAXReader();

Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));

List<Element> elementList = document.getRootElement().elements();

List<Car> carList = new ArrayList<Car>();

for(Element e : elementList){

Car car = new Car();

car.setBand(e.elementText("车牌"));

car.setPlace(e.elementText("产地"));

car.setTime(e.element("车牌").attributeValue("出产时间"));

car.setPrice(Integer.parseInt(e.elementText("单价")));

carList.add(car);

}

System.out.println("按单价排序前:");

show(carList);

System.out.println("按单价排序后:");

sortByPriceDesc(carList);

}

public static void sortByPriceDesc(List<Car> carList) {

Collections.sort(carList);

show(carList);

}

public static void show(List<Car> carList){

if(carList!=null && carList.size()>0){

for(Car car : carList){

System.out.print("车牌:"+car.getBand()+"\t");

System.out.print("产地:"+car.getPlace()+"\t");

System.out.print("单价:"+car.getPrice()+"\t");

System.out.println("出产时间:"+car.getTime());

}

}

}

}javabean中需要让其实现

public class Carimplements Comparable<Car>

Comparable这个接口,并重写其compareTo方法,

调用此集合排序方法Collections.sort(carList);

public int compareTo(Carcar) {

if(this.price<car.getPrice()){

return 1;

}else if(this.price>car.getPrice()){

return -1;

}else{

return 0;

}

}

//使用dom4j其它的API

/*String->XML*/

String text = "<root><res>这是根元素</res></root>";

//主动创建document对象

Document document = DocumentHelper.parseText(text);

//使用缩格形式写XML文件

OutputFormat format = OutputFormat.createPrettyPrint();

OutputStream os = new FileOutputStream("src/cn/itcast/xml/dom4j/string2xml_copy.xml");

XMLWriter xmlWriter = new XMLWriter(os,format);

xmlWriter.write(document);

xmlWriter.close();

 

//创建空XML文件

Document document = DocumentHelper.createDocument();

document.addElement("root").setText("这是根元素");

OutputFormat format = OutputFormat.createPrettyPrint();

OutputStream os = new FileOutputStream("src/cn/itcast/xml/dom4j/empty.xml");

XMLWriter xmlWriter = new XMLWriter(os,format);

xmlWriter.write(document);

xmlWriter.close();

 

/*指定插入次序,默认插入到最后*/

SAXReader saxReader = new SAXReader();

Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));

List<Element> elementList = document.getRootElement().elements();

Element newCarElement = DocumentHelper.createElement("汽车");

newCarElement.setText("这是我的汽车");

elementList.add(1,newCarElement);

OutputFormat format = OutputFormat.createPrettyPrint();

OutputStream os = new FileOutputStream("src/cn/itcast/xml/dom4j/car.xml");

XMLWriter xmlWriter = new XMLWriter(os,format);

xmlWriter.write(document);

xmlWriter.close();

//XML->String

SAXReader saxReader = new SAXReader();

Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));

Element rootElement = document.getRootElement();

Element firstCarElement = (Element)rootElement.elements().get(0);

String xml = firstCarElement.asXML();

System.out.println(xml);

常用的API如下:

SAXReader saxReader = new SAXReader(); SAXReader是dom4j的核心类

Document document = saxReader.read("*.xml")

Document.getRootElement()

Element.getName()

Element.elements():取得该元素下的所有直接子元素

   Element.elementText():从一个元素导航到另一个元素且取出该元素的文本

Element.element("车牌") :从一个元素导航到另一个元素

Element.attributeValue("出产时间"):取得一个元素对应的属性

Element.addElement("单价").setText("40"):添加新元素,同时设置该元素文本的值

OutputFormat format = OutputFormat.createPrettyPrint():使用缩格形式写XML文件

XMLWriter xmlWriter = new XMLWriter(os,format):构造XML写入器

xmlWriter.write(document):将内存中的document对象写入硬盘

firstCarElement.remove(firstCarPriceElement):从直接父元素删除直接子元素

//firstCarPriceElement.getParent().remove(firstCarPriceElement):从直接父元素删除直接子元素

//使用xpath技术取得xml文件中任意级别下的内容

package cn.itcast.xml.xpath;

import java.io.File;

import java.util.List;

import org.dom4j.Document;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;

//使用xpath技术取得xml文件中任意级别下的内容

public class Demo1 {

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

SAXReader reader = new SAXReader();

Document document = reader.read(new File("src/cn/itcast/xml/xpath/car.xml"));

String xpath = "//单价";

Element element = (Element) document.selectSingleNode(xpath);

System.out.println("第一辆汽车的单价是:" +element.getText());

List<Element> elementList = document.selectNodes(xpath);

System.out.println("第二辆汽车的单价是:" +elementList.get(1).getText());

}

}

package cn.itcast.xml.xpath;

 

import java.io.File;

import java.util.Scanner;

import org.dom4j.Document;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;

 

//使用Xpath,模拟用户登录

public class Demo2 {

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

//读取用户在键盘的输入信息

Scanner scanner = new Scanner(System.in);

System.out.print("用户名:");

String username = scanner.nextLine();

System.out.print("密码:");

String password = scanner.nextLine();

//解析XML文件,并查询指定的元素

SAXReader saxReader = new SAXReader();

Document document = saxReader.read(new File("src/cn/itcast/xml/xpath/users.xml"));

String xpath = "//user[@username='"+username+"' and @password='"+password+"']";

Element element = (Element) document.selectSingleNode(xpath);

//输出结果

if(element!=null){

System.out.println("登录成功");

}else{

System.out.println("登录失败");

}

}

}

user.xml

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

<root>

<user id="u01" username="jack" password="123456"/>

<user id="u02" username="marry" password="654321"/>

</root>

基于dom4jxpath技术

  1)能够在xml文件中,快速定位需要元素,无需从根元素一个一个的导航到需要的子元素

Document.selectNodes():取得所有符合xpath格式的元素

Document.selectSingleNode():取得所有符合xpath格式的元素的第一个元素

Node类型是Element/Text/Attribute/Document/...类型的父接口

//使用sax解析器解析xml文件

JAXP(了解)

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

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

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

 

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

解析器可以使用JAXPAPI创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。

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

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

 

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

<车辆清单>

<汽车>

<车牌 出产时间="2011">奥迪</车牌>

<产地>北京</产地>

<单价>30</单价>

</汽车>

</车辆清单>

package cn.itcast.xml.sax;

 

import java.io.File;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;

import org.xml.sax.helpers.DefaultHandler;

 

//使用sax解析器解析xml文件

public class Demo1 {

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

//创建SAX解析器工厂

SAXParserFactory factory = SAXParserFactory.newInstance();

//创建SAX解析器

SAXParser saxParser = factory.newSAXParser();

//加载xml文件

saxParser.parse(

new File("src/cn/itcast/xml/sax/car.xml"),

new MyHandler());

}

}

//自定义SAX处理器

class MyHandler extends DefaultHandler{

private long begin;

public void startDocument(){

System.out.println("解析XML文件开始");

begin = System.currentTimeMillis();

}

public void endDocument() {

System.out.println("解析XML文件结束");

long end = System.currentTimeMillis();

System.out.println("解析XML共用" + (end-begin) + "毫秒");

}

public void startElement(

String uri,

String localName,

String qName,

Attributes attributes){

System.out.println("<"+qName+">");

System.out.println(""+attributes.getLength()+"个属性");

System.out.println(attributes.getValue("出产时间"));

}

public void endElement(

String uri,

String localName,

String qName){

System.out.println("</"+qName+">");

}

public void characters(

char[] ch,

int start,

int length){

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

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

System.out.println(content);

}

}

}

SAX解析器

  1)sun公司提供的一个基于事件的xml解析器

  2)SAXParserSAX解析器的核心类,在使用过程中,需要一个SAX处理器,该处理器必须扩展DefaultHandler

  3)SAX解析器在解析XML文件时,会根据XML文件此时的状态,即开始标签,结束标签,调用SAX处理器对应的方法

  4)SAX解析器在解析XML文件时,自动导航,无需像dom4j一样,人为导航

  5)SAX解析器会将空白字符当作一个有效字符对待

  

简单工厂设计模式

定义:简单工厂模式属于创建型模式有叫做静态工厂方法模式,是一个工厂对象决定创建出哪一种产品类的实例。

简单工厂模式结构图

 

Factory:工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类方法可以被外界直接调用,创建所需的产品对象。

IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

Product:具体产品类,是简单工厂模式的创建目标。

简单工厂模式简单实现

以生产电脑为例:

创建抽象产品类:

public abstract class Computer {/** * 产品的抽象方法,由具体的产品类去实现 */ public abstract void start(); }

穿件具体产品类

public class LenovoComputer extends Computer{@Override public void start() { System.out.println("联想电脑启动"); }

public class HpComputer extends Computer{@Override public void start() { System.out.println("惠普电脑启动"); } }

public class AsusComputer extends Computer {@Override public void start() { System.out.println("华硕电脑启动"); } }

创建工厂类:

提供一个静态方法createComputer方法用来生产电脑,你只需要传入你想生产的电脑品牌,此方法就返回实例化相应品牌的电脑对象。

public class ComputerFactory {

public static Computer createComputer(String type){

Computer mComputer=null;

 switch (type) {

 case "lenovo": mComputer=new LenovoComputer();

break;

case "hp": mComputer=new HpComputer();

break;

case "asus": mComputer=new AsusComputer();

break;

 }

return mComputer;

 }

}