XML文档可以作为应用的配置文件,也可以作为数据交互文件载体,应用越来越广泛,所以一定要掌握如何解析与生成XML文档。
XML是一种通用的数据交换格式,它的平台无关性、语言无关性、系统无关性、给数据集成与交互带来了极大的方便。XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已。
XML的解析方式分为四种:1、DOM解析;2、SAX解析;3、JDOM解析;4、DOM4J解析。其中前两种属于基础方法,是官方提供的平台无关的解析方式;后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。
一、DOM解析
DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。
DOM接口提供了一种通过分层对象模型来访问XML文档信息的方式,这些分层对象模型依据XML的文档结构形成了一棵节点树。无论XML文档中所描述的是什么类型的信息,即便是制表数据、项目列表或一个文档,利用DOM所生成的模型都是节点树的形式。也就是说,DOM强制使用树模型来访问XML文档中的信息。由于XML本质上就是一种分层结构,所以这种描述方法是相当有效的。
DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。
优点:
1、形成了树结构,有助于更好的理解、掌握,且代码容易编写。
2、解析过程中,树结构保存在内存中,方便修改。
缺点:
1、由于文件是一次性读取,所以对内存的耗费比较大。
2、如果XML文件比较大,容易影响解析性能且可能会造成内存溢出。
二:SAX方法
Java原生的XML解析方法之二——SAX方法,原理:通过parse(file,listener)函数用一个listener对xml文件进行查找,按顺序读取文档,遍历每个标签,当发现目标标签
时,读取标签的属性、结点值等信息并返回。
优点:
1、无需将整个xml文档载入内存,因此消耗内存少
2、可以继承ContentHandler创建多个执行不同查询的listener进行解析操作
缺点:
1、不能随机的访问xml中的节点
2、不能修改文档
3、查询依次就要对XML文档从头到尾遍历一次
三:JDOM方法
JDOM方法是根据DOM方法的众多繁琐操作进行包装得到的,上面我们看到,DOM方法解析XML文档其实是很繁琐的,而且很混乱,标签、属性、换行空格都当作结点类型来处理。JDOM方法定义了一系列通俗、好记的方法来解析XML,方法的底层封装了一系列DOM操作,但是我们不必亲自去进行这些繁琐的工作了。
优点:
DOM方式的优点:查找方便,可以修改
缺点
DOM方式的缺点:装载整个文档,对内存容量要求高
四、DOM4J解析
优点:
1、JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功能。
2、它使用接口和抽象基本类方法。
3、具有性能优异、灵活性好、功能强大和极端易用的特点。
4、是一个开放源码的文件
DOM4J例程
XML文件
<?xml version="1.0" encoding="UTF8"?>
<data id="myprop">
<emp>
<empno>Java</empno>
<address>Oracle</address>
<tel>010</tel>
<fax>010</fax>
<email>java@sun.com</email>
</emp>
<emp>
<empno>Oracle</empno>
<address>Oracle</address>
<tel>020</tel>
<fax>020</fax>
<email>oracle@oracle.com</email>
</emp>
</data>
import java.io.File;
import java.io.FileOutputStream;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class Dom4JTest {
public void generateXml(List<UserInfo> lst)
throws Exception
{
Document doc = DocumentHelper.createDocument();
Element root = DocumentHelper.createElement("data");
for(UserInfo ui:lst)
{
Element empEle = DocumentHelper.createElement("emp");
Element empNoEle = DocumentHelper.createElement("empno");
empNoEle.setText(ui.getEmpNo()+"");
empEle.add(empNoEle);
Element empNameEle = DocumentHelper.createElement("empname");
empNameEle.setText(ui.getEmpName());
empEle.add(empNameEle);
Element mgrEle = DocumentHelper.createElement("mgr");
mgrEle.setText(ui.getMgr()+"");
empEle.add(mgrEle);
Element jobEle = DocumentHelper.createElement("job");
jobEle.setText(ui.getJob());
empEle.add(jobEle);
Element deptNoEle = DocumentHelper.createElement("deptno");
deptNoEle.setText(ui.getDeptNo()+"");
empEle.add(deptNoEle);
Element salEle = DocumentHelper.createElement("sal");
salEle.setText(ui.getSal()+"");
empEle.add(salEle);
Element hdEle = DocumentHelper.createElement("hiredate");
hdEle.setText(ui.getHireDate()+"");
empEle.add(hdEle);
root.add(empEle);
}
doc.add(root);
OutputFormat of = new OutputFormat("\t",true);
FileOutputStream fos = new FileOutputStream("e:/emp.xml");
XMLWriter xmlw = new XMLWriter(fos,of);
xmlw.write(doc);
fos.close();
}
public List<UserInfo> parseXml()
throws Exception
{
List<UserInfo> rtn = new ArrayList<UserInfo>();
SAXReader sr = new SAXReader();
Document doc = sr.read(new File("e:/emp.xml"));
Element root = doc.getRootElement();
List lst = root.elements("emp");
for(Iterator it=lst.iterator();it.hasNext();)
{
Element ele = (Element)it.next();
Element empNoEle = ele.element("empno");
String empNo = empNoEle.getText();
Element empNameEle = ele.element("empname");
String empName = empNameEle.getText();
Element mgrEle = ele.element("mgr");
String mgr = mgrEle.getText();
Element jobEle = ele.element("job");
String job = jobEle.getText();
Element deptnoEle = ele.element("deptno");
String deptNo = deptnoEle.getText();
Element salEle = ele.element("sal");
String sal = salEle.getText();
Element hdEle = ele.element("hiredate");
String hd = hdEle.getText();
UserInfo ui = new UserInfo();
ui.setEmpNo(Integer.parseInt(empNo));
ui.setEmpName(empName);
ui.setMgr(Integer.parseInt(mgr));
ui.setJob(job);
ui.setDeptNo(Integer.parseInt(deptNo));
ui.setSal(Integer.parseInt(sal));
ui.setHireDate(Date.valueOf(hd));
rtn.add(ui);
}
return rtn;
}
public static void main(String[] args)
{
try
{
UserInfo ui = new UserInfo();
ui.setEmpNo(1);
ui.setEmpName("java");
ui.setMgr(1);
ui.setJob("Mgr");
ui.setDeptNo(1);
ui.setSal(1000);
ui.setHireDate(new Date(new java.util.Date().getTime()));
List<UserInfo> lst = new ArrayList<UserInfo>();
lst.add(ui);
Dom4JTest d4j = new Dom4JTest();
//d4j.generateXml(lst);
List lst2 = d4j.parseXml();
System.out.println(lst2);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
XML 解析属性与CDATA节点
package com.test.dom4j;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.CDATA;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class XmlAttrParse {
public List<EmpInfo> parseInputStream()
{
List<EmpInfo> emps = new ArrayList<EmpInfo>();
//通过类加载器从类目录中获取文件流对象
InputStream is = this.getClass().getClassLoader().getResourceAsStream("data.xml");
try
{
Document doc = new SAXReader().read(is);
Element root = doc.getRootElement();
List lst = root.elements("emp");
for(Iterator it=lst.iterator();it.hasNext();)
{
Element empEle = (Element)it.next();
Attribute idAtt = empEle.attribute("id");
String id = null;
if(idAtt != null)
{
id = idAtt.getValue();
}
Attribute nameAtt = empEle.attribute("name");
String name = null;
if(nameAtt != null)
{
name = nameAtt.getValue();
}
Element empnoEle = empEle.element("empno");
String empno = empnoEle.getText();
Element addressEle = empEle.element("address");
String address = addressEle.getText();
Element telEle = empEle.element("tel");
String tel = telEle.getText();
Element faxEle = empEle.element("fax");
String fax = faxEle.getText();
Element emailEle = empEle.element("email");
String email = emailEle.getText();
EmpInfo emi = new EmpInfo();
emi.setId(id);
emi.setName(name);
emi.setEmpno(empno);
emi.setAddress(address);
emi.setTel(tel);
emi.setFax(fax);
emi.setEmail(email);
emps.add(emi);
}
}
catch(Exception e)
{
e.printStackTrace();
}
return emps;
}
public List<EmpInfo> parse(String file)
{
List<EmpInfo> emps = new ArrayList<EmpInfo>();
try
{
//通过文件绝对目录加载文件对象
File f = new File(file);
Document doc = new SAXReader().read(f);
//获取XML根节点,每个XML中只有一个根节点
Element root = doc.getRootElement();
//获取根节点下emp节点集合列表对象
List lst = root.elements("emp");
//循环遍历集合对象
for(Iterator it=lst.iterator();it.hasNext();)
{
//迭代器中每个元素是Dom4J的Element对象类型
Element empEle = (Element)it.next();
Attribute idAtt = empEle.attribute("id");
String id = null;
if(idAtt != null)
{
id = idAtt.getValue();
}
Attribute nameAtt = empEle.attribute("name");
String name = null;
if(nameAtt != null)
{
name = nameAtt.getValue();
}
//根据节点名称获取节点对象Element
Element empnoEle = empEle.element("empno");
String empno = empnoEle.getText();
Element addressEle = empEle.element("address");
String address = addressEle.getText();
Element telEle = empEle.element("tel");
String tel = telEle.getText();
Element faxEle = empEle.element("fax");
String fax = faxEle.getText();
Element emailEle = empEle.element("email");
String email = emailEle.getText();
//定义Java对象装载XML中的数据
EmpInfo emi = new EmpInfo();
emi.setId(id);
emi.setName(name);
emi.setEmpno(empno);
emi.setAddress(address);
emi.setTel(tel);
emi.setFax(fax);
emi.setEmail(email);
//将新生成对象放到集合中
emps.add(emi);
}
}
catch(Exception e)
{
e.printStackTrace();
}
return emps;
}
public void writeXml(List<EmpInfo> emps)
{
try
{
Document doc = DocumentHelper.createDocument();
Element root = DocumentHelper.createElement("data");
doc.setRootElement(root);
for(EmpInfo ei:emps)
{
Element empEle = DocumentHelper.createElement("emp");
Attribute idAtt = DocumentHelper.createAttribute(empEle, "id", ei.getId());
empEle.add(idAtt);
Attribute nameAtt = DocumentHelper.createAttribute(empEle, "name", ei.getName());
empEle.add(nameAtt);
root.add(empEle);
Element empnoEle = DocumentHelper.createElement("empno");
empEle.add(empnoEle);
CDATA cdata = DocumentHelper.createCDATA(ei.getEmpno());
empnoEle.add(cdata);
Element addrEle = DocumentHelper.createElement("address");
empEle.add(addrEle);
addrEle.setText(ei.getAddress());
Element telEle = DocumentHelper.createElement("tel");
empEle.add(telEle);
telEle.setText(ei.getTel());
Element faxEle = DocumentHelper.createElement("fax");
empEle.add(faxEle);
faxEle.setText(ei.getFax());
Element emailEle = DocumentHelper.createElement("email");
empEle.add(emailEle);
emailEle.setText(ei.getEmail());
}
OutputFormat of = new OutputFormat("\t",true);
FileOutputStream fos = new FileOutputStream("d:/my.xml");
XMLWriter xmlw = new XMLWriter(fos,of);
xmlw.write(doc);
fos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public byte[] writeXmlBytes(List<EmpInfo> emps)
{
try
{
Document doc = DocumentHelper.createDocument();
Element root = DocumentHelper.createElement("data");
doc.setRootElement(root);
for(EmpInfo ei:emps)
{
Element empEle = DocumentHelper.createElement("emp");
Attribute idAtt = DocumentHelper.createAttribute(empEle, "id", ei.getId());
empEle.add(idAtt);
Attribute nameAtt = DocumentHelper.createAttribute(empEle, "name", ei.getName());
empEle.add(nameAtt);
root.add(empEle);
Element empnoEle = DocumentHelper.createElement("empno");
empEle.add(empnoEle);
CDATA cdata = DocumentHelper.createCDATA(ei.getEmpno());
empnoEle.add(cdata);
Element addrEle = DocumentHelper.createElement("address");
empEle.add(addrEle);
addrEle.setText(ei.getAddress());
Element telEle = DocumentHelper.createElement("tel");
empEle.add(telEle);
telEle.setText(ei.getTel());
Element faxEle = DocumentHelper.createElement("fax");
empEle.add(faxEle);
faxEle.setText(ei.getFax());
Element emailEle = DocumentHelper.createElement("email");
empEle.add(emailEle);
emailEle.setText(ei.getEmail());
}
OutputFormat of = new OutputFormat("\t",true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XMLWriter xmlw = new XMLWriter(baos,of);
xmlw.write(doc);
return baos.toByteArray();
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
XmlAttrParse xp = new XmlAttrParse();
String file = "D:/workspace2/EC5_Proj_Blank/src/main/resources/data.xml";
List<EmpInfo> emps = xp.parse(file);
byte[] data = xp.writeXmlBytes(emps);
System.out.println(new String(data));
}
}