您的位置:首页 > 其它

XML解析

2016-02-21 18:23 267 查看
XML解析

Java自带的解析XML通常有两种方式:DOM和SAX。假如这儿有一个person.xml文档。

person.xml

<?xml version="1.0" encoding="UTF-8"?>
<code>
<person id="1">
<name>张三</name>
<age>18</age>
<sex>男</sex>
<tel>18335161111</tel>
</person>

<person id="2">
<name>李四</name>
<age>20</age>
<sex>男</sex>
<tel>18335168888</tel>
</person>
</code>


1. DOM解析XML

DOM:Document Object Model(文档对象模型),定义了访问和操作文档的标准方法。DOM定义了一组Java接口,基于对象,与语言和平台无关将XML文档表示为树,在内存中解析和存储XML文档,允许随机访问文档的不同部分。

DOM解析的特点:

整个文档都加载进内存(占内存),灵活性好,API简单,以树形结构存储。

使用DOM解析person.xml

Person.java

package com.oner.wv;

public class Person {
private String id;
private String name;
private int age;
private String sex;
private String tel;

public Person() {
super();
}

public Person(String id, String name, int age, String sex, String tel) {
super();
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
this.tel = tel;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getTel() {
return tel;
}

public void setTel(String tel) {
this.tel = tel;
}

@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age
+ ", sex=" + sex + ", tel=" + tel + "]";
}

}


DomDemo.java

package com.oner.wv;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DomDemo {

public static void main(String[] args) {
List<Person> list = parseDomXML();
for (Person person : list) {
System.out.println(person);
}
}

private static List<Person> parseDomXML() {
// 创建一个文档解析工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 创建一个接收容器
List<Person> list = new ArrayList<Person>();
Person person = null;

try {
// 由文档解析工厂得到文档解析对象
DocumentBuilder builder = factory.newDocumentBuilder();
// 封装xml文件
InputStream is = new FileInputStream(new File(
"src/com/oner/wv/person.xml"));
// 把XML文件的输入流放入解析器中进行解析,这时就将xml文件装载到了内存中了
Document doc = builder.parse(is);

// 从解析器中获取person元素集合
NodeList personList = doc.getElementsByTagName("person");
// System.out.println(personList.getLength());
for (int i = 0; i < personList.getLength(); i++) {
// 得到每个person元素
Node personNode = personList.item(i);
person = new Person();
// 获取person元素的id属性
String id = personNode.getAttributes().getNamedItem("id")
.getNodeValue();
// System.out.println(id);
// 将获取到的id值赋给Person实例
person.setId(id);
// 获取person元素的子元素集合
NodeList childList = personNode.getChildNodes();
for (int j = 0; j < childList.getLength(); j++) {
// 得到每个person元素的子元素
Node childNode = childList.item(j);
// 得到每个person元素的子元素的名称
String name = childNode.getNodeName();
// System.out.println(name);
// 得到每个person元素的子元素的文本结点的内容,并将其赋值给Person类实例
if ("name".equals(name)) {
person.setName(childNode.getFirstChild().getNodeValue());
} else if ("age".equals(name)) {
person.setAge(Integer.parseInt(childNode
.getFirstChild().getNodeValue()));
} else if ("sex".equals(name)) {
person.setSex(childNode.getFirstChild().getNodeValue());
} else if ("tel".equals(name)) {
person.setTel(childNode.getFirstChild().getNodeValue());
}
}
// System.out.println(person);
// 将得到的Person实例添加到list集合中
list.add(person);
}

} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}

}


运行结果:



2. SAX解析XML

SAX,全称Simple API for XML,既是一种接口,也是一种软件包。它是一种XML解析的替代方法。SAX不同于DOM解析,它逐行扫描文档,一边扫描一边解析。由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势。

SAX解析:

PersonHandler.java

package com.oner.wv;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
* 数据处理器
*
* @author Oner.wv
*
*/
public class PersonHandler extends DefaultHandler {

private List<Person> list;
private Person person;
private String tag;// 标记名称

public List<Person> getList() {
return list;
}

public void setList(List<Person> list) {
this.list = list;
}

@Override
// 开始解析文档
public void startDocument() throws SAXException {
list = new ArrayList<Person>();
System.out.println("开始解析文档啦");
}

@Override
// 文档解析结束
public void endDocument() throws SAXException {
System.out.println("文档解析结束");
}

@Override
// 开始解析节点
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if ("person".equals(qName)) {
person = new Person();
// 获取person元素的id属性,并将其赋值给Person类实例
person.setId(attributes.getValue("id"));
}

tag = qName;
}

@Override
// 保存节点内容
public void characters(char[] ch, int start, int length)
throws SAXException {
if (tag != null) {
if ("name".equals(tag)) {
person.setName(new String(ch, start, length));
} else if ("age".equals(tag)) {
person.setAge(Integer.parseInt(new String(ch, start, length)));
} else if ("sex".equals(tag)) {
person.setSex(new String(ch, start, length));
} else if ("tel".equals(tag)) {
person.setTel(new String(ch, start, length));
}
}
}

@Override
// 结束解析节点
public void endElement(String uri, String localName, String qName)
throws SAXException {
tag = null;
if ("person".equals(qName)) {
list.add(person);
}
}

}


SAXDemo.java

package com.oner.wv;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

/**
* 基于事件移动,不占内存,灵活性差,顺序读取,速度快,适用于性能要求较高的设备上使用
*
* @author Oner.wv
*
*/
public class SAXDemo {

public static void main(String[] args) {
List<Person> list = parseSAXXML();
for (Person person : list) {
System.out.println(person);
}
}

private static List<Person> parseSAXXML() {
List<Person> list = new ArrayList<Person>();
// 解析器工厂
SAXParserFactory factory = SAXParserFactory.newInstance();

try {
// 生成解析器
SAXParser sax = factory.newSAXParser();
// 封装xml文件
InputStream is = new FileInputStream(new File(
"src/com/oner/wv/person.xml"));
PersonHandler dh = new PersonHandler();
sax.parse(is, dh);// 解析
list = dh.getList();
} catch (ParserConfigurationException | SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return list;
}

}


     运行结果:



3. JDOM解析XML

JDOM简化了与XML的交互并且比使用DOM实现更快,JDOM与DOM主要有两方面区别。首先,JDOM仅使用 了具体类而不使用接口,这在某些方面简化了API,但是也限制了灵活性。第二,大量使用了 Collections类,简化了那些已经熟悉这些类的Java开发者的使用。

JDomDemo.java

package com.oner.wv;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

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

public class JDomDemo {

public static void main(String[] args) {
List<Person> list = parseJDomXML();
for (Person person : list) {
System.out.println(person);
}
}

private static List<Person> parseJDomXML() {

List<Person> list = new ArrayList<Person>();
SAXBuilder builder = new SAXBuilder();
try {
InputStream is = new FileInputStream(new File(
"src/com/oner/wv/person.xml"));
// 解析文档
Document doc = builder.build(is);
// 获取根结点
Element root = doc.getRootElement();
List<Element> rootList = root.getChildren();
for (int i = 0; i < rootList.size(); i++) {
Element e = rootList.get(i);
Person person = new Person();
person.setId(e.getAttributeValue("id"));
System.out.println(e.getAttributeValue("id"));
List<Element> personList = e.getChildren();
for (int j = 0; j < personList.size(); j++) {
Element personNode = personList.get(j);
String tag = personNode.getName();
System.out.println(tag);
if ("name".equals(tag)) {
person.setName(personNode.getText());
} else if ("age".equals(tag)) {
person.setAge(Integer.parseInt(personNode.getText()));
} else if ("sex".equals(tag)) {
person.setSex(personNode.getText());
} else if ("tel".equals(tag)) {
person.setTel(personNode.getText());
}
}
list.add(person);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return list;
}
}


运行结果:



4. DOM4J解析

dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面还可以找到一篇文章,对主流的Java
XML API进行的性能、功能和易用性的评测,所以可以知道dom4j无论在哪个方面都是非常出色的。如今可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这已经是必须使用的jar包, Hibernate也用它来读写配置文件。

Dom4JDemo.java

package com.oner.wv;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Dom4JDemo {

public static void main(String[] args) {
List<Person> list = parseDom4JXML();
for (Person person : list) {
System.out.println(person);
}
}

private static List<Person> parseDom4JXML() {

List<Person> list = new ArrayList<Person>();
SAXReader reader = new SAXReader();
try {
InputStream is = new FileInputStream(new File(
"src/com/oner/wv/person.xml"));
Document doc = reader.read(is);
Element root = doc.getRootElement();
Iterator<Element> iter = root.elementIterator();
while (iter.hasNext()) {
Element e = iter.next();
Iterator<Element> i = e.elementIterator();
Person person = new Person();
person.setId(e.attributeValue("id"));
while (i.hasNext()) {
Element el = i.next();
String tag = el.getName();
if ("name".equals(tag)) {
person.setName(el.getText());
} else if ("age".equals(tag)) {
person.setAge(Integer.parseInt(el.getText()));
} else if ("sex".equals(tag)) {
person.setSex(el.getText());
} else if ("tel".equals(tag)) {
person.setTel(el.getText());
}
}
list.add(person);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
return list;
}

}


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  XML解析 DOM SAX DOM4J