一、解析Xml的四种方法
1、DOM
为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。
优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
2、SAX
为解决DOM的问题,出现了SAX。SAX是事件驱动,当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。所谓事件驱动,是指一种基于回调(callback)机制的程序运行方法
优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。
缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;
使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;
3、JDOM
JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。
优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM文档。
使用具体类而不是接口,简化了DOM的API。大量使用了Java集合类,方便了Java开发人员。
缺点:没有较好的灵活性,性能较差。
4、DOM4J
简单易用,采用Java集合框架,并完全支持DOM、SAX和JAXP
优点:大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。支持XPath。有很好的性能。
缺点:大量使用了接口,API较为复杂。
二、SAX、DOM4J使用示例
Xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="1">
<age>1</age>
<name>sky</name>
</person>
<person id="2">
<age>2</age>
<name>cain</name>
</person>
</persons>
Bean:
package com.learn.xml;
public class Person {
private String id;
private String age;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Element :定义XML元素。例:person、age、name等都属于元素
Attribute:定义XML的属性。例:person的id属性
1、SAX
Bean处理器(解析xml):
package com.learn.xml;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class BeanListHandler extends DefaultHandler {
//存放遍历集合
private List<Person> persons = new ArrayList<>();
//构建对象
private Person person;
//存放遍历后的节点名称
private String preTag;
//返回遍历对象
public List<Person> getPersons()
{
return persons;
}
//开始解析Element
@Override
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException
{
if("person".equals(qName))
{
person = new Person();
person.setId(attributes.getValue(0));
}
preTag = qName;
}
//可获取该Element的值,重写执行相关操作
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
String content = new String(ch,start,length);
if("age".equals(preTag))
{
person.setAge(content);
}
if("name".equals(preTag))
{
person.setName(content);
}
}
//结束解析该Element
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
if("person".equals(qName))
{
persons.add(person);
person = null;
}
preTag = null;
}
}
测试类:package com.learn.xml;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
public class SaxReadXml {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
BeanListHandler sax = new BeanListHandler();
InputStream stream = SaxReadXml.class.getResourceAsStream("/config/test.xml");
parser.parse(stream, sax);
List<Person> persons = sax.getPersons();
for(Person p : persons)
{
System.out.println("Id:" + p.getId() + " 姓名:" + p.getName() + " 年龄:" + p.getAge());
}
}
}
结果:
Id:1 姓名:sky 年龄:1
Id:2 姓名:cain 年龄:2
2、DOM4J
导入dom4j-1.6.1.jar jaxen-1.1.1.jar 使用xPath需jaxen的jar包。
package com.learn.xml;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Dom4jReadXml {
public static void main(String[] args) throws DocumentException {
InputStream input = Dom4jReadXml.class.getResourceAsStream("/config/test.xml");
SAXReader sax = new SAXReader();
Document doc = sax.read(input);
//找到所有person Element
List<Element> rowList = doc.selectNodes("//person");
Iterator<Element> it = rowList.iterator();
//遍历节点
while(it.hasNext())
{
Map<String,String> nodeMap = new HashMap<>();
Element element = (Element)it.next();
//输出Attribute
System.out.println(element.attribute(0).getName()+":"+element.attribute(0).getValue());
//获取person下的子Element
List<Element> elementList = element.elements();
Iterator<Element> child = elementList.iterator();
while(child.hasNext())
{
//获取子Element并输出
Element e = (Element)child.next();
nodeMap.put(e.getName(), element.elementText(e.getName()));
System.out.println(e.getName()+":"+element.elementText(e.getName()));
}
}
}
}
结果:
id:1
age:1
name:sky
id:2
age:2
name:cain
解析XML形式的文本,利用DocumentHelper获取Document对象
String text = "<person></person>"
Document document = DocoumentHelper.parseText(text);

被折叠的 条评论
为什么被折叠?



