dom4j介绍  dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory

dom4j是一个简单的开源库,用于处理XML、 XPath和XSLT,它基于Java平台,使用Java的集合框架,全面集成了DOM,SAX和JAXP。

dom4j的使用

下载了dom4j项目之后,解压缩,将其jar包(我的当前版本叫做dom4j-1.6.1.jar)加入class path下面。

(Properties->Java Build Path -> Add External JARs...)。

之后就可以使用其提供的API进行编程。

程序实例1

第一个程序,用Java代码生成xml文档,代码如下:

package com.example.xml.dom4j;

import java.io.FileOutputStream;

import java.io.FileWriter;

import org.dom4j.Document;

import org.dom4j.DocumentHelper;

import org.dom4j.Element;

import org.dom4j.io.OutputFormat;

import org.dom4j.io.XMLWriter;

/**

* dom4j框架学习 使用dom4j框架创建xml文档并输出保存

*

*/

public class Dom4JTest1

{

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

{

// 第一种方式:创建文档,并创建根元素

// 创建文档:使用了一个Helper类

Document document = DocumentHelper.createDocument();

// 创建根节点并添加进文档

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

document.setRootElement(root);

// 第二种方式:创建文档并设置文档的根元素节点

Element root2 = DocumentHelper.createElement("student");

Document document2 = DocumentHelper.createDocument(root2);

// 添加属性

root2.addAttribute("name", "zhangsan");

// 添加子节点:add之后就返回这个元素

Element helloElement = root2.addElement("hello");

Element worldElement = root2.addElement("world");

helloElement.setText("hello Text");

worldElement.setText("world text");

// 输出

// 输出到控制台

XMLWriter xmlWriter = new XMLWriter();

xmlWriter.write(document);

// 输出到文件

// 格式

OutputFormat format = new OutputFormat(" ", true);// 设置缩进为4个空格,并且另起一行为true

XMLWriter xmlWriter2 = new XMLWriter(

new FileOutputStream("student.xml"), format);

xmlWriter2.write(document2);

// 另一种输出方式,记得要调用flush()方法,否则输出的文件中显示空白

XMLWriter xmlWriter3 = new XMLWriter(new FileWriter("student2.xml"),

format);

xmlWriter3.write(document2);

xmlWriter3.flush();

// close()方法也可以

}

}

程序Console输出:

生成的一个xml文档:

hello Text

world text

程序实例2

程序实例2,读入xml文档并分析,将其内容输出。

首先,待分析的文档如下:

hello Text1

hello Text2

hello Text3

world text1

world text2

world text3

package com.example.xml.dom4j;

import java.io.File;

import java.util.Iterator;

import java.util.List;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import org.dom4j.Document;

import org.dom4j.Element;

import org.dom4j.io.DOMReader;

import org.dom4j.io.SAXReader;

/**

* dom4j框架学习: 读取并解析xml

*

*

*/

public class Dom4JTest2

{

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

{

SAXReader saxReader = new SAXReader();

Document document = saxReader.read(new File("students.xml"));

// 获取根元素

Element root = document.getRootElement();

System.out.println("Root: " + root.getName());

// 获取所有子元素

List childList = root.elements();

System.out.println("total child count: " + childList.size());

// 获取特定名称的子元素

List childList2 = root.elements("hello");

System.out.println("hello child: " + childList2.size());

// 获取名字为指定名称的第一个子元素

Element firstWorldElement = root.element("world");

// 输出其属性

System.out.println("first World Attr: "

+ firstWorldElement.attribute(0).getName() + "="

+ firstWorldElement.attributeValue("name"));

System.out.println("迭代输出-----------------------");

// 迭代输出

for (Iterator iter = root.elementIterator(); iter.hasNext();)

{

Element e = (Element) iter.next();

System.out.println(e.attributeValue("name"));

}

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

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

DocumentBuilder db = dbf.newDocumentBuilder();

// 注意要用完整类名

org.w3c.dom.Document document2 = db.parse(new File("students.xml "));

DOMReader domReader = new DOMReader();

// 将JAXP的Document转换为dom4j的Document

Document document3 = domReader.read(document2);

Element rootElement = document3.getRootElement();

System.out.println("Root: " + rootElement.getName());

}

}

代码运行后输出:

Root: students

total child count: 6

hello child: 3

first World Attr: name=wangwu

迭代输出-----------------------

lisi

lisi2

lisi3

wangwu

wangwu2

null

用DOMReader-----------------------

Root: students

SAX解析XML下面是SAX实现实体解析的步骤

//下面使用XMLReader 来解析

(一)第一步:新建一个工厂类SAXParserFactory,代码如下:

SAXParserFactory factory = SAXParserFactory.newInstance();

(二)第二步:让工厂类产生一个SAX的解析类SAXParser,代码如下:

SAXParser parser = factory.newSAXParser();

(三)第三步:从SAXPsrser中得到一个XMLReader实例,代码如下:

XMLReader reader = parser.getXMLReader();

(四)第四步:把自己写的handler注册到XMLReader中,一般最重要的就是ContentHandler,代码如下:

reader.setContentHandler(this);

(五)第五步:将一个xml文档或者资源变成一个java可以处理的InputStream流后,解析正式开始,代码如下:

reader.parse(new InputSource(is));

//下面使用SAXParser来解析

(一)第一步:新建一个工厂类SAXParserFactory,代码如下:

SAXParserFactory factory = SAXParserFactory.newInstance();

(二)第二步:让工厂类产生一个SAX的解析类SAXParser,代码如下:

SAXParser parser = factory.newSAXParser();

(三)第三步:将一个xml文档或者资源变成一个java可以处理的InputStream流后,解析正式开始,代码如下:

parser.parse(is,this);

估计大家都看到了ContentHandler ,下面具体的讲下

解析开始之前,需要向XMLReader/SAXParser 注册一个ContentHandler,也就是相当于一个事件监听器,在ContentHandler中定义了很多方法

//设置一个可以定位文档内容事件发生位置的定位器对象

public void setDocumentLocator(Locator locator)

//用于处理文档解析开始事件

public void startDocument()throws SAXException

//处理元素开始事件,从参数中可以获得元素所在名称空间的uri,元素名称,属性类表等信息

public void startElement(String namespacesURI , String localName , String qName , Attributes atts) throws SAXException

//处理元素结束事件,从参数中可以获得元素所在名称空间的uri,元素名称等信息

public void endElement(String namespacesURI , String localName , String qName) throws SAXException

//处理元素的字符内容,从参数中可以获得内容

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

顺便介绍下XMLReader中的方法。

//注册处理XML文档解析事件ContentHandler

public void setContentHandler(ContentHandler handler)

//开始解析一个XML文档

public void parse(InputSorce input) throws SAXException

大概的讲的差不多了  接下来开始讲解解析的步骤

我们还是用上一章的代码

首先 我们创建一个Person类  用来存储用户的信息

package com.example.demo;

import java.io.Serializable;

public class Person implements Serializable {

/**

*

*/

private static final long serialVersionUID = 1L;

private String _id;

private String _name;

private String _age;

public String get_id() {

return _id;

}

public void set_id(String _id) {

this._id = _id;

}

public String get_name() {

return _name;

}

public void set_name(String _name) {

this._name = _name;

}

public String get_age() {

return _age;

}

public void set_age(String _age) {

this._age = _age;

}

}

接下来  我们要实现一个ContentHandler 用来解析XML

实现一个ContentHandler 一般需要下面几个步骤

1、声明一个类,继承DefaultHandler。DefaultHandler是一个基类,这个类里面简单实现了一个ContentHandler。我们只需要重写里面的方法即可。

2、重写 startDocument() 和 endDocument(),一般将正式解析之前的初始化放到startDocument()里面,收尾的工作放到endDocument()里面。

3、重写startElement(),XML解析器遇到XML里面的tag时就会调用这个函数。经常在这个函数内是通过对localName的值进行判断而操作一些数据。

4、重写characters()方法,这是一个回调方法。解析器执行完startElement()后,解析节点的内容后就会执行这个方法,并且参数ch[]就是节点的内容。

5、重写endElement()方法,这个方法与startElement()相对应,解析完一个tag节点后,执行这个方法,解析一个tag后,调用这个处理还原和清除相关信息

首先   新建一个类 继承DefaultHandler 并重写以下几个方法

public class SAX_parserXML extends DefaultHandler {

/**

* 当开始解析xml文件的声明的时候就会触发这个事件, 可以做一些初始化的工作

* */

@Override

public void startDocument() throws SAXException {

// TODO Auto-generated method stub

super.startDocument();

}

/**

* 当开始解析元素的开始标签的时候,就会触发这个事件

* */

@Override

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

Attributes attributes) throws SAXException {

// TODO Auto-generated method stub

super.startElement(uri, localName, qName, attributes);

}

/**

* 当读到文本元素的时候要触发这个事件.

* */

@Override

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

throws SAXException {

// TODO Auto-generated method stub

super.characters(ch, start, length);

}

/**

* 当读到结束标签的时候 就会触发这个事件

* */

@Override

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

throws SAXException {

// TODO Auto-generated method stub

super.endElement(uri, localName, qName);

}

}

首先  我们创建一个list  用来保存解析出来的person数据

List persons;

但是?在哪里初始化呢?我们可以在startDocument()里面初始化,因为当开始解析xml文件的声明的时候就会触发这个事件所以放在这里比较合适

/**

* 当开始解析xml文件的声明的时候就会触发这个事件, 可以做一些初始化的工作

* */

@Override

public void startDocument() throws SAXException {

// TODO Auto-generated method stub

super.startDocument();

// 初始化list

persons = new ArrayList();

}

接下来  就要开始解析了

/**

* 当开始解析元素的开始标签的时候,就会触发这个事件

* */

@Override

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

Attributes attributes) throws SAXException {

// TODO Auto-generated method stub

super.startElement(uri, localName, qName, attributes);

// 如果读到是person标签 开始存储

if (localName.equals("person")) {

person = new Person();

person.set_id(attributes.getValue("id"));

}

curNode = localName;

}

上面的代码中  localName表示当前解析到的元素名

//步骤

//1.判断是否是person元素

//2.创建新的Person对象

//3.获取id 添加到Person对象中

curNode 用来保存当前的元素名 在characters中会使用到

/**

* 当读到文本元素的时候要触发这个事件.

* */

@Override

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

throws SAXException {

// TODO Auto-generated method stub

super.characters(ch, start, length);

if (person != null) {

//取出目前元素对应的值

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

//判断元素是否是name

if (curNode.equals("name")) {

//将取出的值添加到person对象

person.set_name(txt);

} else if (curNode.equals("age")) {

person.set_age(txt);

}

}

}

接下来是介绍标签结束的时候需要做的事情

/**

* 当读到结束标签的时候 就会触发这个事件

* */

@Override

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

throws SAXException {

// TODO Auto-generated method stub

super.endElement(uri, localName, qName);

// 如果是 并且person不为空,添加到list

if (localName.equals("person") && person != null) {

persons.add(person);

person = null;

}

curNode = "";

}

解析的事情结束了  大概流程就是

1.一个元素开始时    会调用startElement方法

2.接下来会调用到characters方法,可以用来获取元素的值

3.一个元素结束时    会调用到endElement方法

解析结束之后  我们需要写一个方法  用来获取解析后保存的list

public List ReadXML(InputStream is) {

SAXParserFactory factory = SAXParserFactory.newInstance();

try {

SAXParser parser = factory.newSAXParser();

// 第一种方法

// parser.parse(is, this);

// 第二种方法

XMLReader reader = parser.getXMLReader();

reader.setContentHandler(this);

reader.parse(new InputSource(is));

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

return persons;

}

上面的代码就不解释了   只要将inputStream对象传入  就可以解析出内容

看完了代码,我来给出完整的代码

package com.example.demo.Utils;

import java.io.InputStream;

import java.util.ArrayList;

import java.util.List;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;

import org.xml.sax.InputSource;

import org.xml.sax.SAXException;

import org.xml.sax.XMLReader;

import org.xml.sax.helpers.DefaultHandler;

import com.example.demo.Person;

public class SAX_parserXML extends DefaultHandler {

List persons;

Person person;

// 当前节点

String curNode;

public List ReadXML(InputStream is) {

SAXParserFactory factory = SAXParserFactory.newInstance();

try {

SAXParser parser = factory.newSAXParser();

// 第一种方法

// parser.parse(is, this);

// 第二种方法

XMLReader reader = parser.getXMLReader();

reader.setContentHandler(this);

reader.parse(new InputSource(is));

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

return persons;

}

/**

* 当开始解析xml文件的声明的时候就会触发这个事件, 可以做一些初始化的工作

* */

@Override

public void startDocument() throws SAXException {

// TODO Auto-generated method stub

super.startDocument();

// 初始化list

persons = new ArrayList();

}

/**

* 当开始解析元素的开始标签的时候,就会触发这个事件

* */

@Override

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

Attributes attributes) throws SAXException {

// TODO Auto-generated method stub

super.startElement(uri, localName, qName, attributes);

// 如果读到是person标签 开始存储

if (localName.equals("person")) {

person = new Person();

person.set_id(attributes.getValue("id"));

}

curNode = localName;

}

/**

* 当读到文本元素的时候要触发这个事件.

* */

@Override

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

throws SAXException {

// TODO Auto-generated method stub

super.characters(ch, start, length);

if (person != null) {

// 取出目前元素对应的值

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

// 判断元素是否是name

if (curNode.equals("name")) {

// 将取出的值添加到person对象

person.set_name(txt);

} else if (curNode.equals("age")) {

person.set_age(txt);

}

}

}

/**

* 当读到结束标签的时候 就会触发这个事件

* */

@Override

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

throws SAXException {

// TODO Auto-generated method stub

super.endElement(uri, localName, qName);

// 如果是person结尾 并且person不为空,添加到list

if (localName.equals("person") && person != null) {

persons.add(person);

person = null;

}

curNode = "";

}

}

写个方法调用下这个类

List persons = new SAX_parserXML().ReadXML(is);

StringBuffer buffer = new StringBuffer();

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

Person person =persons.get(i);

buffer.append("id:" + person.get_id() + " ");

buffer.append("name:" + person.get_name() + " ");

buffer.append("age:" + person.get_age() + "\n");

}

Toast.makeText(activity, buffer, Toast.LENGTH_LONG).show();

如果你看到下面的界面  说明解析成功了~

小结:

DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了。

优点:整个文档读入内存,方便操作:支持修改、删除和重现排列等多种功能。

缺点:将整个文档读入内存中,保留了过多的不需要的节点,浪费内存和空间。

使用场合:一旦读入文档,还需要多次对文档进行操作,并且在硬件资源充足的情况下(内存,CPU)。

为了解决DOM解析存在的问题,就出现了SAX解析。其特点为:

优点:不用实现调入整个文档,占用资源少。尤其在嵌入式环境中,如android,极力推荐使用SAX解析。

缺点:不像DOM解析一样将文档长期驻留在内存中,数据不是持久的。如果事件过后没有保存数据,数据就会丢失。

使用场合:机器有性能限制

java 解析xml saxreader_Java中使用DOM和SAX解析XML文件的方法示例相关推荐

  1. java sax解析xml_在Java中使用DOM,SAX和StAX解析器解析XML

    java sax解析xml 我碰巧通读了有关Java中XML解析和构建API的章节. 我试用了样本XML上的其他解析器. 然后,我想在我的博客上分享它,这样我就可以得到该代码的参考以及任何阅读此代码的 ...

  2. 在Java中使用DOM,SAX和StAX解析器解析XML

    我碰巧通读了有关Java中的XML解析和构建API的章节. 我试用了样本XML上的其他解析器. 然后,我想在我的博客上分享它,这样我就可以参考该代码以及任何阅读此书的参考. 在本文中,我将在不同的解析 ...

  3. Android中三种常用解析XML的方式(DOM、SAX、PULL)简介及区别

    XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能.今天就由我向大家介绍一下在Android平台下几种常见的XML解 ...

  4. JAXP进行DOM和SAX解析

    1.常用XML的解析方式:DOM和SAX 1)DOM思想:将整个XML加载内存中,形成文档对象,所以对XML操作都对内存中文档对象进行. 2)SAX思想:一边解析,一边处理,一边释放内存资源---不允 ...

  5. 题目:以下选项中关于DOM和SAX的说法错误的是()

    题目: 以下选项中关于DOM和SAX的说法错误的是() A.DOM和SAX都是目前常用的XML解析技术 B.DOM把XML文档映射成一个倒挂的树状结构 C.DOM模型内存消耗小,DOM解析器能提供更好 ...

  6. python 读取pdf cid_python使用pdfminer解析pdf文件的方法示例

    最近要做个从 pdf 文件中抽取文本内容的工具,大概查了一下 python 里可以使用 pdfminer 来实现.下面就看看怎样使用吧. PDFMiner是一个可以从PDF文档中提取信息的工具.与其他 ...

  7. python合并txt文本_Python实现将目录中TXT合并成一个大TXT文件的方法

    本文实例讲述了Python实现将目录中TXT合并成一个大TXT文件的方法.分享给大家供大家参考.具体如下: 在网上下了一个dota的英雄攻略,TXT格式,每个英雄一个文件,看得疼,就写了一个小东西,合 ...

  8. python亿级mysql数据库导出_Python实现将MySQL数据库表中的数据导出生成csv格式文件的方法...

    本文实例讲述了python实现将MySQL数据库表中的数据导出生成csv格式文件的方法.分享给大家供大家参考,具体如下: #!/usr/bin/env python # -*- coding:utf- ...

  9. Pycharm中无法通过点击查看csv文件解决方法

    Pycharm中无法通过点击查看csv文件 问题描述: Pycharm中无法像上图中一样通过点击打开csv文件 解决方法: 在Pycharm项目界面中找到对应文件,鼠标左键双击,此时右下角会出现红色感 ...

  10. S7-200SMART_MODBUS RTU通信轮询中实现插队写入或条件写入的具体方法示例(1)

    S7-200SMART_MODBUS RTU通信轮询中实现插队写入或条件写入的具体方法示例(1) 前面的博文中和大家分享了MODBUS RTU通信轮询的具体方法,感兴趣的可以参考以下链接中的内容: S ...

最新文章

  1. Python 技术篇 - 通过代码查看文本的编码类型实例演示,如何查看文件的编码类型,文件编码查看方法
  2. UDF、UDAF、UDTF函数编写
  3. 这 8 份「Paper + Code」,你一定用得上 | PaperDaily #08
  4. php按照字段合并数组,PHP实现数组根据某个字段进行水平合并横向合并代码实例...
  5. 设计人员珍藏的在线处理图片的网址大集合
  6. python网络爬虫与信息提取北京理工大学_Python网络爬虫与信息提取(一)
  7. ansys本地的help文件_linux - 远程拷贝文件之rsync
  8. 《软件需求分析(第二版)》第 3 章——需求工程的推荐方法 重点部分总结
  9. Java_BigInteger
  10. 数据镜像备份工具rsync + inotify
  11. js获取字符串的字节数
  12. mysql like 贪婪匹配_mysql模糊查询like与REGEXP的使用详细介绍
  13. python编程入门教程100例_Python3入门经典100例(60-70)
  14. Launcher分析修改记录(1)----序
  15. 万亿安防市场前景可期 未来四大发展趋势分析
  16. Adobe Audition 基本使用
  17. 推荐几款不错的Chrome 插件
  18. cdLinux显示“没有发现无限网卡!”
  19. Android手机游戏大全apk
  20. 转载:Java导出数据到Excel

热门文章

  1. 扩展linux swap分区大小,扩展Linux系统swap分区的大小
  2. 通过银行卡号,识别相应的银行信息
  3. 使用MVC2模式创建新闻网站
  4. sql server 函数--rand() 生成整数的随机数
  5. Hibernate中Java对象的生命周期
  6. POJ1159 Palindrome(dp)
  7. java面向接口编程详解
  8. 分布式事务各方案对比分析
  9. Oracle常见索引扫描方式总结
  10. javascript 密码花园 并不清晰的js基础 总结(1)