四种XML解析方法:
(1)Dom生成和解析XML文档
*解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。
* 优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
* 缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
* 使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
(2)SAX生成和解析XML文档
* SAX ,事件驱动。
* 当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。
* 优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。
* 缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;
* 无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;
* 使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;
(3)DOM4J生成和解析XML文档
* DOM4J 是一个非常非常优秀的Java XML API,
* 具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。
* 如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。
(4)JDOM生成和解析XML
*为减少DOM、SAX的编码量,出现了JDOM;
*优点:20-80原则,极大减少了代码量。
*使用场合:要实现的功能简单,如解析、创建等,
*但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。
首先编写一个要解析的test.xml文件
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<employees>
<employee>
<name>wxyfree</name>
<age>30</age>
</employee>
<employee>
<name>freewxy</name>
<age>22</age>
</employee>
</employees>
然后,编写一个XMLDocument接口
/**
* 定义XML文档建立与解析的接口
* @author wxy
*
*/
public interface XMLDocument {
/**
*建立XML文档
* @param fileName 文件全路径名
*/
public void createXML(String fileName);
/**
* 解析XML文档
* @param fileName 文件全路径名
*/
public void parseXML(String fileName);
}
一、
package review.testXML;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* Dom生成和解析XML文档
* 为 XML 文档的已解析版本定义了一组接口。
* 解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。
* 优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
* 缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
* 使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
* @param args
*/
public class DomDemo implements XMLDocument {
private Document document;
private String fileName;
public void init(){
try{
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
this.document=builder.newDocument();
}catch(ParserConfigurationException e){
System.out.println(e.getMessage());
}
}
@Override
public void createXML(String fileName) {
Element root=this.document.createElement("employees");//创建根元素
this.document.appendChild(root);
Element employee=this.document.createElement("employee");//创建子元素
Element name=this.document.createElement("name");//添加元素的属性
name.appendChild(this.document.createTextNode("wxyfree"));
employee.appendChild(name);//将元素添加到子元素中
Element sex=this.document.createElement("sex");
sex.appendChild(this.document.createTextNode("m"));
Element age=this.document.createElement("age");
age.appendChild(this.document.createTextNode("30"));
employee.appendChild(age);
root.appendChild(employee);//将子元素添加到根元素中
TransformerFactory tf=TransformerFactory.newInstance();//此抽象类的实例能够将源树转为结果树
try{
Transformer transformer=tf.newTransformer();
DOMSource source=new DOMSource(document);//创建带有DOM节点的新输入源
transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");//设置转换中世纪的输出属性
transformer.setOutputProperty(OutputKeys.INDENT, "yes");//
PrintWriter pw=new PrintWriter(new FileOutputStream(fileName));
StreamResult result=new StreamResult(pw);//充当转换结果的持有者,可以为xml、纯文本、HTML或某些其他格式的标记
transformer.transform(source, result);//将XML Source转换为Result
System.out.println("生成XML文件成功");
}catch(TransformerConfigurationException e){
System.out.println(e.getMessage());
} catch (TransformerException e) {
System.out.println(e.getMessage());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
}
@Override
public void parseXML(String fileName) {
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db;
try {
db = dbf.newDocumentBuilder();
Document document = db.parse(fileName);
NodeList employees=document.getChildNodes();
for(int i=0;i<employees.getLength();i++){
Node employee=employees.item(i);
NodeList employeeInfo=employee.getChildNodes();
for(int j=0;j<employeeInfo.getLength();j++){
Node node=employeeInfo.item(j);
NodeList employeeMeta=node.getChildNodes();
for(int k=0;k<employeeMeta.getLength();k++){
System.out.println(employeeMeta.item(k).getNodeName()+":"+employeeMeta.item(k).getTextContent());
}
}
}
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("解析完毕");
}
public static void main(String[] args){
DomDemo d=new DomDemo();
d.init();
d.createXML("conf/test2.xml");
d.parseXML("conf/test.xml");
}
}
二、
package review.testXML;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* SAX ,事件驱动。
* 当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。
* 优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。
* 缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;
* 无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;
* 使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;
* @author wxy
*
*/
public class SaxDemo implements XMLDocument{
@Override
public void createXML(String fileName) {
System.out.println("<<"+fileName+">>");
}
@Override
public void parseXML(String fileName) {
SAXParserFactory saxfac=SAXParserFactory.newInstance();
try {
SAXParser saxParser=saxfac.newSAXParser();
InputStream ins=new FileInputStream(fileName);
saxParser.parse(ins,new MySAXHandler());
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
} catch (SAXException e) {
System.out.println(e.getMessage());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
/**
* @param args
*/
public static void main(String[] args) {
SaxDemo s=new SaxDemo();
s.parseXML("conf/test.xml");
}
}
class MySAXHandler extends DefaultHandler{
boolean hasAttribute=false;
Attributes attributes=null;
/**
* Receive notification of the beginning of the document.
*/
public void startDocument()throws SAXException{
System.out.print("文档开始打印了");
}
/**
* Receive notification of the end of the document.
*/
public void endDocument()throws SAXException{
System.out.print("文档开始结束了");
}
/**
* Receive notification of the start of an element.
* @param uri The Namespace URI, or the empty string if the
* element has no Namespace URI or if Namespace
* processing is not being performed.
* @param localName The local name (without prefix), or the
* empty string if Namespace processing is not being
* performed.
* @param qName The qualified name (with prefix), or the
* empty string if qualified names are not available.
* @param attributes The attributes attached to the element. If
* there are no attributes, it shall be an empty
* Attributes object.
* @exception org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
*/
public void startElement(String uri,String localName,String qName,Attributes attributes)throws SAXException{
if(qName.equals("employees")){return;}
if(qName.equals("employee")){
System.out.print(qName);
}
if(attributes.getLength()>0){
this.attributes=attributes;
this.hasAttribute=true;
}
}
/**
* Receive notification of the end of an element.
* @param uri The Namespace URI, or the empty string if the
* element has no Namespace URI or if Namespace
* processing is not being performed.
* @param localName The local name (without prefix), or the
* empty string if Namespace processing is not being
* performed.
* @param qName The qualified name (with prefix), or the
* empty string if qualified names are not available.
* @exception org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
*/
public void endElement(String uri,String localName,String qNaqme)throws SAXException{
if(hasAttribute&&(attributes!=null)){
for(int i=0;i<attributes.getLength();i++){
System.out.print(attributes.getQName(0)+attributes.getValue(0));
}
}
}
/**
* Receive notification of character data inside an element.
* @param ch The characters.
* @param start The start position in the character array.
* @param length The number of characters to use from the
* character array.
*/
public void characters(char[] ch,int start,int length)throws SAXException{
System.out.print(new String(ch,start,length));
}
}
三、
package review.testXML;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* Dom4j 生成XML文档与解析XML文档
* DOM4J 是一个非常非常优秀的Java XML API,
* 具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。
* 如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。
* @author wxy
*
*/
public class Dom4jDemo implements XMLDocument{
@Override
public void createXML(String fileName) {
Document document = DocumentHelper.createDocument();
Element employees=document.addElement("employees");
Element employee=document.addElement("employee");
Element name=employee.addElement("name");
name.setText("wxy");
Element sex=employee.addElement("sex");
name.setText("f");
Element age=employee.addElement("age");
name.setText("29");
try {
Writer fileWriter=new FileWriter(fileName);
XMLWriter xmlWriter=new XMLWriter(fileWriter);
xmlWriter.write(document);
xmlWriter.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
@Override
public void parseXML(String fileName) {
File inputXML=new File(fileName);
SAXReader saxReader=new SAXReader();
try {
Document document=saxReader.read(inputXML);
Element employees=document.getRootElement();
for(Iterator i=employees.elementIterator();i.hasNext();){
Element employee=(Element)i.next();
for(Iterator j=employee.elementIterator();j.hasNext();){
Element node=(Element)j.next();
System.out.println(node.getName()+":"+node.getText());
}
}
} catch (DocumentException e) {
System.out.println(e.getMessage());
}
System.out.println("dom4j parserXML");
}
public static void main(String[] args) {
Dom4jDemo d=new Dom4jDemo();
d.parseXML("conf/test.xml");
}
}
四、
package review.testXML;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
/**
* JDOM生成和解析XML
*为减少DOM、SAX的编码量,出现了JDOM;
*优点:20-80原则,极大减少了代码量。
*使用场合:要实现的功能简单,如解析、创建等,
*但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。
* @author wxy
*
*/
public class JDomDemo implements XMLDocument{
@Override
public void createXML(String fileName) {
Document document;
Element root;
root=new Element("employees");
document=new Document(root);
Element employee=new Element("employee");
root.addContent(employee);
Element name=new Element("name");
name.setText("wxywxy");
employee.addContent(name);
Element sex=new Element("sex");
sex.setText("m");
employee.addContent(sex);
Element age=new Element("age");
age.setText("25");
employee.addContent(age);
XMLOutputter XMLOut=new XMLOutputter();
try {
XMLOut.output(document, new FileOutputStream(fileName));
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
@Override
public void parseXML(String fileName) {
SAXBuilder builder=new SAXBuilder(false);
try {
Document document=builder.build(fileName);
Element employees=document.getRootElement();
List employeeList=employees.getChildren("employee");
for(int i=0;i<employeeList.size();i++){
Element employee=(Element)employeeList.get(i);
List employeeInfo=employee.getChildren();
for(int j=0;j<employeeInfo.size();j++){
System.out.println(((Element)employeeInfo.get(j)).getName()+":"+((Element)employeeInfo.get(j)).getText());
}
}
} catch (JDOMException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args){
JDomDemo jd=new JDomDemo();
jd.parseXML("conf/test.xml");
}
}