您的位置:首页 > 其它

DOM4J与JDOM解析xml文档

2015-12-21 15:37 288 查看

1. JDOM方式解析XML

  JDOM并不是java官方解析xml文档的方法,所以在进行文档解析前,需要下载JDOM的jar包:http://www.jdom.org/downloads/;并将其路径添加到当前项目中,或者把jar包拷贝到当前项目中。

同样地使用前面的books.xml文档进行解析:

books.xml:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.0</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">Learing XML</title>
<author>Erik T. Ray</author>
<year>2010</year>
<price>48.99</price>
</book>
</bookstore>


Books抽象类:

package demo;

/**
* 根据xml “books”文档,新创建Books类
* Created by luts on 2015/12/21.
*/
public class Books {
private String category;
private String title;
private String language;
private String author;
private String year;
private String price;

public String getCategory() {
return category;
}

public void setCategory(String category) {
this.category = category;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getLanguage() {
return language;
}

public void setLanguage(String language) {
this.language = language;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public String getYear() {
return year;
}

public void setYear(String year) {
this.year = year;
}

public String getPrice() {
return price;
}

public void setPrice(String price) {
this.price = price;
}
}


JDOM解析xml文档:

package demo;

import org.jdom2.Attribute;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.JDOMParseException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.Document;

import javax.imageio.IIOException;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
* Created by luts on 2015/12/21.
*/
public class JDOMTest {
private static ArrayList<Books> booksList = new ArrayList<Books>();

public static void main(String[]args){
//创建一个SAXBuilder的对象
SAXBuilder saxBuilder = new SAXBuilder();
InputStream inputStream;
try {
//创建一个输入流,将xml文件加载到输入流中
inputStream = new FileInputStream("books.xml");
InputStreamReader isr = new InputStreamReader(inputStream, "UTF-8");
//通过saxBuilder的build方法,将输入流加载到saxBuilder中
Document document = saxBuilder.build(isr);
//通过document对象获取xml文件的根节点
Element rootElement = document.getRootElement();
//获取节点下的的子节点的List结合
List<Element> bookList = rootElement.getChildren();
//继续解析
for (Element book : bookList){
Books bookEntry = new Books();
System.out.println("-------------开始解析第" + (bookList.indexOf(book) + 1) + "书------------");
//解析book的属性集合
List<Attribute> attrList = book.getAttributes();
//知道节点下的属性名称时,获取节点值
//book.getAttribute("category");
for (Attribute attr : attrList){

//获取属性名
String attrName = attr.getName();
//获取属性值
String attrValue = attr.getValue();
System.out.println("属性名: " + attrName + "----属性值:" + attrValue);
if (attrName.equals("category")) {
bookEntry.setCategory(attrValue);
}
}

//对book节点的子节点名以及节点值的遍历
List<Element> bookChilds = book.getChildren();
for (Element child : bookChilds){
System.out.println("节点名: " + child.getName() + "----属性值: "+ child.getValue());
if (child.getName().equals("title")){

bookEntry.setTitle(child.getValue());
//知道节点下的属性名称时,获取节点值
String lang = child.getAttributeValue("lang");
bookEntry.setLanguage(lang);
System.out.println("title   包含的属性 lang 的属性值为: " + child.getAttributeValue("lang"));
/* List<Attribute> childAttrList = child.getAttributes();
for (Attribute childAttr : childAttrList){

//获取属性名
String childAttrName = childAttr.getName();
//获取属性值
String childAttrValue = childAttr.getValue();
System.out.println("属性名: " + childAttrName + "----属性值:" + childAttrValue);
if (childAttrName.equals("lang")) {
bookEntry.setLanguage(childAttrName);
}
}*/
}
else if (child.getName().equals("author")){
bookEntry.setAuthor(child.getValue());
}
else if (child.getName().equals("year")){
bookEntry.setYear(child.getValue());
}
else if (child.getName().equals("price")){
bookEntry.setPrice(child.getValue());
}
}
System.out.println("------结束解析第" + (bookList.indexOf(book) + 1) + "本书-------");
booksList.add(bookEntry);
bookEntry = null;
System.out.println(booksList.size());
System.out.println(booksList.get(0).getCategory());
System.out.println(booksList.get(0).getTitle());
System.out.println(booksList.get(0).getAuthor());
System.out.println(booksList.get(0).getLanguage());
}
}
catch (FileNotFoundException e){
e.printStackTrace();
}
catch (JDOMException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}

}
}


测试结果:

-------------开始解析第1书------------
属性名: category----属性值:COOKING
节点名: title----属性值: Everyday Italian
title   包含的属性 lang 的属性值为: en
节点名: author----属性值: Giada De Laurentiis
节点名: year----属性值: 2005
节点名: price----属性值: 30.0
------结束解析第1本书-------
1
COOKING
Everyday Italian
Giada De Laurentiis
en
-------------开始解析第2书------------
属性名: category----属性值:CHILDREN
节点名: title----属性值: Harry Potter
title   包含的属性 lang 的属性值为: en
节点名: author----属性值: J K. Rowling
节点名: year----属性值: 2005
节点名: price----属性值: 29.99
------结束解析第2本书-------
2
COOKING
Everyday Italian
Giada De Laurentiis
en
-------------开始解析第3书------------
属性名: category----属性值:WEB
节点名: title----属性值: Learing XML
title   包含的属性 lang 的属性值为: en
节点名: author----属性值: Erik T. Ray
节点名: year----属性值: 2010
节点名: price----属性值: 48.99
------结束解析第3本书-------
3
COOKING
Everyday Italian
Giada De Laurentiis
en


2. DOM4J方法解析xml

  同样的,因为DOM4J不是java官方定义的xml文档解析方法,所以得下载DOM4J的jar包:http://www.dom4j.org/dom4j-1.6.1/

实例:

book.xml

 <?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.0</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">Learing XML</title>
<author>Erik T. Ray</author>
<year>2010</year>
<price>48.99</price>
</book>
</bookstore>


Book.java

package demo;

/**
* 根据xml “books”文档,新创建Books类
* Created by luts on 2015/12/21.
*/
public class Books {
private String category;
private String title;
private String language;
private String author;
private String year;
private String price;

public String getCategory() {
return category;
}

public void setCategory(String category) {
this.category = category;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getLanguage() {
return language;
}

public void setLanguage(String language) {
this.language = language;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public String getYear() {
return year;
}

public void setYear(String year) {
this.year = year;
}

public String getPrice() {
return price;
}

public void setPrice(String price) {
this.price = price;
}
}


DOM4J解析xml文档

package demo;

import jdk.internal.org.xml.sax.Attributes;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* 使用DOM4J方法解析xml文档
* Created by luts on 2015/12/21.
*/
public class DOM4JTest {
private static ArrayList<Books>bookList = new ArrayList<Books>();

public static void main(String[]args){

//创建SAXReader的对象
SAXReader reader = new SAXReader();
try {
//通过reader对象的read方法加载books.xml文档,获取document对象
Document document = reader.read(new File("books.xml"));
//通过document对象获取根节点bookstore
Element bookStore = document.getRootElement();
//通过element对象的elementIterator方法获取迭代器
Iterator it = bookStore.elementIterator();
while (it.hasNext()){
Books bookAdd = new Books();
System.out.println("-------开始解析某一本书-----------");
Element book = (Element) it.next();
//获取book的属性名以及属性值
List<Attribute> bookAttrs = book.attributes();
for (Attribute attr: bookAttrs){
System.out.println("属性名: " + attr.getName() + "----属性值: " + attr.getValue());
if (attr.getName().equals("category")){
bookAdd.setCategory(attr.getValue());
}
}
Iterator itt = book.elementIterator();
while (itt.hasNext()){
Element bookChild = (Element) itt.next();
System.out.println("节点名: " + bookChild.getName() + "----节点值:" + bookChild.getStringValue());
if (bookChild.getName().equals("title")){
bookAdd.setTitle(bookChild.getStringValue());
List<Attribute> bookChildAttrs = bookChild.attributes();
for (Attribute attrChild: bookChildAttrs){
System.out.println("属性名: " + attrChild.getName() + "----属性值: " + attrChild.getValue());
bookAdd.setLanguage(attrChild.getValue());
}
}
else if (bookChild.getName().equals("author")){
bookAdd.setAuthor(bookChild.getStringValue());
}
else if (bookChild.getName().equals("year")){
bookAdd.setYear(bookChild.getStringValue());
}
else if (bookChild.getName().equals("price")){
bookAdd.setPrice(bookChild.getStringValue());
}

}
System.out.println("------遍历完某一本书---------");
bookList.add(bookAdd);
bookAdd = null;
}

System.out.println();

System.out.println("队列中有" + bookList.size() + "本书\n" + "------开始遍历队列中的书本---------");

Iterator listIt = bookList.iterator();
for (Books bookitem : bookList){
System.out.println("第" +( bookList.indexOf(bookitem) + 1) + "本书包含的属性为: ");
System.out.println(bookitem.getCategory());
System.out.println(bookitem.getLanguage());
System.out.println(bookitem.getTitle());
System.out.println(bookitem.getAuthor());
System.out.println(bookitem.getYear());
System.out.println(bookitem.getPrice());
}

}
catch (DocumentException E){
E.printStackTrace();
}
}
}


结果:

-------开始解析某一本书-----------
属性名: category----属性值: COOKING
节点名: title----节点值:Everyday Italian
属性名: lang----属性值: en
节点名: author----节点值:Giada De Laurentiis
节点名: year----节点值:2005
节点名: price----节点值:30.0
------遍历完某一本书---------
-------开始解析某一本书-----------
属性名: category----属性值: CHILDREN
节点名: title----节点值:Harry Potter
属性名: lang----属性值: en
节点名: author----节点值:J K. Rowling
节点名: year----节点值:2005
节点名: price----节点值:29.99
------遍历完某一本书---------
-------开始解析某一本书-----------
属性名: category----属性值: WEB
节点名: title----节点值:Learing XML
属性名: lang----属性值: en
节点名: author----节点值:Erik T. Ray
节点名: year----节点值:2010
节点名: price----节点值:48.99
------遍历完某一本书---------

队列中有3本书
------开始遍历队列中的书本---------
第1本书包含的属性为:
COOKING
en
Everyday Italian
Giada De Laurentiis
2005
30.0
第2本书包含的属性为:
CHILDREN
en
Harry Potter
J K. Rowling
2005
29.99
第3本书包含的属性为:
WEB
en
Learing XML
Erik T. Ray
2010
48.99


3. 4 种解析方法的比较

1)DOM(Document Object Model)

  文档对象模型分析方式。以层次结构(类似于树型)来组织节点和信息片段,映射XML文档的结构,允许获取和操作文档的任意部分。是W3C的官方标准。

优点:
  1、允许应用程序对数据和结构做出更改。
  2、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。

缺点:
  1、通常需要加载整个XML文档来构造层次结构,消耗资源大

2)SAX(Simple API for XML)

  流模型中的推模型分析方式。通过事件驱动,每发现一个节点就引发一个事件,通过回调方法完成解析工作,解析XML文档的逻辑需要应用程序完成。

优点:
  1、不需要等待所有数据都被处理,分析就能立即开始。
  2、只在读取数据时检查数据,不需要保存在内存中。
  3、可以在某个条件得到满足时停止解析,不必解析整个文档。
  4、效率和性能较高,能解析大于系统内存的文档。

缺点:
  1、需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),使用麻烦。
  2、单向导航,很难同时访问同一文档的不同部分数据,不支持XPath。

3)JDOM(Java-based Document Object Model)

  Java特定的文档对象模型。自身不包含解析器,使用SAX。

优点:
  1、使用具体类而不是接口,简化了DOM的API。
  2、大量使用了Java集合类,方便了Java开发人员。

缺点:
  1、没有较好的灵活性。
  2、性能较差。

4)DOM4J(Document Object Model for Java)

  简单易用,采用Java集合框架,并完全支持DOM、SAX和JAXP。

优点:
  1、大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。
  2、支持XPath。
  3、有很好的性能。

缺点:
  1、大量使用了接口,API较为复杂

扩展阅读:四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: