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,length)));
} else if ("sex".equals(tag)) {
person.setSex(new String(ch,length));
} else if ("tel".equals(tag)) {
person.setTel(new String(ch,length));
}
}
}
@Override
// 结束解析节点
public void endElement(String uri,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;
}
}
运行结果:
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|