1.SAX解析XML文件
2.DOM解析XML文件
3.JDOM解析XML文件
4.DOM4J解析XML文件
注意:XML文件的解析格式有两种:SAX解析和DOM解析(DOM , JDOM , DOM4J )
各种解析方法比较:
1.JDOM与DOM4J在性能测试时表示不佳,在测试10M的文档时内存溢出.
2.SAX表现较好,这主要依赖于与它特定的解析方式.一个SAX检测即将到来的XML流,但并没有载入内存 (当然在XML流被读入时,会有部分文档暂时隐藏于内存中)
3.DOM4J是这场测试中的获胜者,目前许多开源的项目中大量使用DOM4J,例如(Hibernate框架也使用DOM4J来读取XML配置文件.
步骤:
1.创建一个SAX解析器工厂对象
2.通过工厂对象创建一个SAX解析器对象
3.创建一个数据处理器(需要自己编写)
4.开始解析XML文件
特点:
1.基于事件驱动
即在解析XML文件的中每一个标签时,都会回调数据处理器中所重写的方法.
2.顺序读取,速度快
从上到下依次读取
3.不可以任意读取节点 ,灵活性差
4.解析是占用的内存小.
5.SAX更适用于对性能要求较高的设备上使用(例:Andriod开发)
public void saxParseXML() throws ParserConfigurationException, SAXException, IOException {
//1.创建一个SAX解析器工厂对象
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//2.通过工厂对象创建一个SAX解析器对象
SAXParser saxParser = saxParserFactory.newSAXParser();
//3.创建一个数据处理器对象(数据处理器需要自己编写)
PersonHandler personHandler = new PersonHandler();
//4.开始解析XML文件
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("com/xml/person.xml");
saxParser.parse(resourceAsStream, personHandler);
List<Person> persons = personHandler.getPersons();
for (Person person : persons) {
System.out.println(person);
}
数据处理器 PersonHandler类
package com.xml;
import com.sun.org.apache.bcel.internal.generic.NEW;
import com.sun.org.apache.bcel.internal.generic.VariableLengthInstruction;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.naming.Name;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: 薛云冲
* Created on 2019/4/25 22:45
*/
public class PersonHandler extends DefaultHandler {
private List<Person> persons = new ArrayList<>();
private Person p;//当前正在解析的person.
private String tag;//用于记录当前正在解析的标签名.
public List<Person> getPersons(){
return persons;
}
/*
在开始解析XML文档时调用
*/
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("开始解析文档...");
}
/*
在XML文档解析结束时调用
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("解析文档结束...");
}
/**
* @param uri 命名空间
* @param localName 不带前缀的标签名
* @param qName 带前缀的标签名
* @param attributes 当前标签的属性集合
* @throws SAXException
*/
/*
解析开始元素时调用
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if("person".equals(qName)){
p = new Person();
String value = attributes.getValue("personid");
p.setPersonid(value);
}
tag = qName;
}
/*
解析结束元素时调用
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if ("person".equals(qName)) {
persons.add(p);
}
tag = null ;
}
/*
解析内容时调用.
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
if(tag!=null){
if ("name".equals(tag)) {
p.setName(new String(ch, start, length));
}else if("address".equals(tag)){
p.setAddress(new String(ch,start,length));
}else if("tel".equals(tag)){
p.setTel(new String(ch,start,length));
}else if("fax".equals(tag)){
p.setFax(new String(ch,start,length));
}else if("email".equals(tag)){
p.setEmail(new String(ch,start,length));
}
}
}
}
person.xml文件的内容
<people>
<person personid="E01">
<name>Tony Blairname>
<address>10 Downing Street,London,UKaddress>
<tel>(061) 98765tel>
<fax>(061) 98765fax>
<email>[email protected]email>
person>
<person personid="E02">
<name>Bill Clintonname>
<address>White House,USAaddress>
<tel>(001) 6400 98765tel>
<fax>(001) 6400 98765fax>
<email>[email protected]email>
person>
people>
步骤:
1.创建一个DOM解析器(文档生成器)工厂对象
2.通过工厂对象创建一个DOM解析器对象
3.解析文档
4.从内存中读取数据生成对象
特点:
1.基于树型结构,
2.通过解析器一次性把文档加载到内存中,所以会比较占用内存,
3.可以随机访问,更加灵活,适合web端开发.
@Test
public void domParseXML() throws IOException, SAXException, ParserConfigurationException {
// 1.创建一个DOM解析器(文档生成器)工厂对象
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
// 2.通过工厂对象创建一个DOM解析器对象
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
// 3.解析文档
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("com\\xml\\person.xml");
//此代码完成后,整个XML文档已经被加载到内存中,以树状形式存储;
Document parse = documentBuilder.parse(resourceAsStream);
// 4.从内存中读取数据生成对象
//获取节点名称为person的所有节点,返回节点集合.
NodeList personNodeList = parse.getElementsByTagName("person");
ArrayList<Person> persons = new ArrayList<>();
Person person = null;
//次循环会迭代两次
for (int i = 0; i < personNodeList.getLength(); i++) {
Node personNode = personNodeList.item(i);
person = new Person();
//获取节点属性值;
String personid = personNode.getAttributes().getNamedItem("personid").getNodeValue();
person.setPersonid(personid);
//获取当前节点的所有子节点
NodeList childNodes = personNode.getChildNodes();
for (int j = 0; j <childNodes.getLength() ; j++) {
Node item = childNodes.item(j);
String nodeName = item.getNodeName();
if("name".equals(nodeName)){
person.setName(item.getFirstChild().getNodeValue());
}else if("address".equals(nodeName)){
person.setTel(item.getFirstChild().getNodeValue());
}
else if("tel".equals(nodeName)){
person.setTel(item.getFirstChild().getNodeValue());
}
else if("fax".equals(nodeName)){
person.setFax(item.getFirstChild().getNodeValue());
}
else if("email".equals(nodeName)){
person.setEmail(item.getFirstChild().getNodeValue());
}
}
persons.add(person);
}
System.out.println("结果:");
for (Person person1 : persons) {
System.out.println(person1);
}
}
步骤:
1.创建JDOM解析器
2.解析文档
3.从内存中读取数据生成对象
特点:
1.基于树型结构
2.第三方组件
3.与DOM的区别:
(1).第三方开源组件.
(2).实现使用JAVA的Collection接口.
(3).效率比DOM更加快,更容易让使用者接受.
@Test
public void jdomParseXML() throws JDOMException, IOException {
//1.创建JDOM解析器
SAXBuilder builder = new SAXBuilder();
//2.解析文档
//将资源转化为流
InputStream resourceAsStream = Thread.currentThread()
.getContextClassLoader().getResourceAsStream("com\\xml\\person.xml");
//解析资源流
org.jdom2.Document build = builder.build(resourceAsStream);
//3.从内存中读取数据生成对象
//得到根元素
Element rootElement = build.getRootElement();
List<Person> persons = new ArrayList<>();
Person person =null;
List<Element> children = rootElement.getChildren();
for (Element child : children) {
person =new Person();
String attributeValue = child.getAttributeValue("personid");
person.setPersonid(attributeValue);
List<Element> children1 = child.getChildren();
for (Element element : children1) {
String name = element.getName();
if("name".equals(name)){
person.setName(element.getText());
}else if("address".equals(name)){
person.setAddress(element.getText());
}else if("tel".equals(name)){
person.setTel(element.getText());
}else if("fax".equals(name)){
person.setFax(element.getText());
}else if("email".equals(name)){
person.setEmail(element.getText());
}
}
persons.add(person);
}
for (Person p : persons) {
System.out.println(p);
}
}
步骤:
1.创建DOM4J解析器
2.解析文档
3.从内存中读取数据生成对象
特点:
1.基于树型结构
2.第三方组件
3.解析速度快,效率更高,使用JAVA中的迭代器进行数据读取,在web框架中使用较多,比如(Hibernate框架)
@Test
public void dom4jParseXML() throws DocumentException {
//1.创建DOM4J解析器对象
SAXReader reader = new SAXReader();
//2.解析文件
//将xml文件转化为流
InputStream resourceAsStream = Thread.currentThread()
.getContextClassLoader().getResourceAsStream("com\\xml\\person.xml");
//解析资源流
org.dom4j.Document read = reader.read(resourceAsStream);
//3.从内存中读取数据生成对象
//获取根元素
org.dom4j.Element rootElement = read.getRootElement();
List<Person> persons = new ArrayList<>();
Person person = null;
//获取子节点
Iterator<org.dom4j.Element> iterator = rootElement.elementIterator();
while (iterator.hasNext()){
person = new Person();
org.dom4j.Element next = iterator.next();
person.setPersonid(next.attributeValue("personid"));
//获取子节点
Iterator<org.dom4j.Element> iterator1 = next.elementIterator();
while (iterator1.hasNext()){
org.dom4j.Element next1 = iterator1.next();
String name = next1.getName();
if("name".equals(name)){
person.setName(next1.getText());
}else if("address".equals(name)){
person.setAddress(next1.getText());
}else if("tel".equals(name)){
person.setTel(next1.getText());
}else if("fax".equals(name)){
person.setFax(next1.getText());
}else if("email".equals(name)){
person.setEmail(next1.getText());
}
}
persons.add(person);
}
for (Person person1 : persons) {
System.out.println(person1);
}
}
public void xmlEnCoder() throws FileNotFoundException {
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("test.xml"));
XMLEncoder xmlEncoder = new XMLEncoder(bufferedOutputStream);
Person p =new Person();
p.setPersonid("1001");
p.setName("盖伦");
p.setAddress("德玛西亚");
p.setFax("6000101011");
p.setTel("6000101011");
p.setEmail("[email protected]");
xmlEncoder.writeObject(p);
xmlEncoder.close();
System.out.println("写入完成...");
}
/*
从xml文件中读取对象
*/
@Test
public void xmlDeCoder() throws FileNotFoundException {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("person.xml"));
XMLDecoder xmlDecoder = new XMLDecoder(bufferedInputStream);
Person person = (Person)xmlDecoder.readObject();
xmlDecoder.close();
System.out.println("读取成功...");
System.out.println(person);
}