DOM,SAX,JDOM,DOM4J優缺點比較及生產xml和解析xml
阿新 • • 發佈:2019-01-01
下載必要的jar包:
activation.jar
commons-logging-1.0.4.jar
dom4j-1.6.1.jar
jaxen-1.1.1.jar
jdom-1.0.jar
一、DOM
解析器讀入整個文件,然後構建一個駐留記憶體的樹結構,使用 DOM 介面來操作這個樹結構。
優點:整個文件樹在記憶體中,便於操作;支援刪除、修改、重新排列等多種功能;訪問效率高。
缺點:將整個文件調入記憶體(包括無用的節點),浪費時間和空間;使用場合:一旦解析了文件還需多次訪問這些資料;硬體資源充足(記憶體、CPU)
package xmlParse; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Calendar; import java.util.Locale; import java.util.TimeZone; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.Result; 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.DOMException; 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; /** * java自帶的dom解析xml檔案 * * @author abc * */ public class TestDom { public static void main(String[] args) { builXmlByDom(); parseXmlByDom(); } /** * 生成xml資訊 */ public static void builXmlByDom() { long begintime = System.currentTimeMillis(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { //構建Document DocumentBuilder db = dbf.newDocumentBuilder(); Document doc=db.newDocument(); Element root=doc.createElement("students"); root.setAttribute("class", "一班"); root.setAttribute("count", "3"); Element stu=doc.createElement("student"); Element name=doc.createElement("name"); name.appendChild(doc.createTextNode("小明")); Element age=doc.createElement("age"); age.appendChild(doc.createTextNode("10")); stu.appendChild(name); stu.appendChild(age); root.appendChild(stu); stu=doc.createElement("student"); stu.setAttribute("position","班長"); name=doc.createElement("name"); name.appendChild(doc.createTextNode("小王")); age=doc.createElement("age"); age.appendChild(doc.createTextNode("11")); stu.appendChild(name); stu.appendChild(age); root.appendChild(stu); stu=doc.createElement("student"); name=doc.createElement("name"); name.appendChild(doc.createTextNode("小兵")); age=doc.createElement("age"); age.appendChild(doc.createTextNode("12")); stu.appendChild(name); stu.appendChild(age); root.appendChild(stu); doc.appendChild(root); //將被變換的Document物件封裝到一個DOMSource物件中 DOMSource xmlSource=new DOMSource(doc); //使用 Transformer物件將一個Document節點變換為一個XML檔案 TransformerFactory transFactory=TransformerFactory. newInstance(); Transformer transformer=transFactory.newTransformer(); //建立Result File file=new File("students.xml"); FileOutputStream fos; fos = new FileOutputStream(file); StreamResult result=new StreamResult(fos); transformer.transform(xmlSource, result); if(fos!=null){ fos.close(); } }catch (ParserConfigurationException e) { e.printStackTrace(); }catch (TransformerConfigurationException e) { e.printStackTrace(); }catch (FileNotFoundException e) { e.printStackTrace(); }catch (TransformerException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } System.out.println("dom生成時間(毫秒)" + (System.currentTimeMillis() - begintime)); } /** * 解析xml資訊 */ public static void parseXmlByDom() { long begintime = System.currentTimeMillis();; try { DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); DocumentBuilder builder=dbf.newDocumentBuilder(); File file=new File("students.xml"); Document doc=builder.parse(file); NodeList students=doc.getFirstChild().getChildNodes(); Node student=null; Node node=null; for(int i=0,len=students.getLength();i<len;i++){ student=students.item(i); NodeList childs=student.getChildNodes(); System.out.println("第"+(i+1)+"個學生"); for(int j=0,size=childs.getLength();j<size;j++){ node=childs.item(j); if("name".equals(node.getNodeName())){ System.out.println(node.getNodeName()+"---"+node.getTextContent()); } if("age".equals(node.getNodeName())){ System.out.println(node.getNodeName()+"---"+node.getTextContent()); } } } } catch (DOMException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println("dom解析時間(毫秒)" + (System.currentTimeMillis() - begintime)); } }
二、SAX
特點: 1、邊讀邊解析,應用於大型XML文件
2、只支援讀
3、訪問效率低
4、順序訪問
package xmlParse; import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class TestSAXParse { /** * @param args */ public static void main(String[] args) { sax(); } public static void sax() { long begintime = System.currentTimeMillis(); File f = new File("students.xml"); SAXParserFactory sf = SAXParserFactory.newInstance(); try { SAXParser sp = sf.newSAXParser(); SAXHandler handler = new SAXHandler(); sp.parse(f, handler); } catch (Exception e) { e.printStackTrace(); } System.out.println("sax解析時間(毫秒)" + (System.currentTimeMillis() - begintime)); } } SAXHandler.java package xmlParse; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import java.util.Stack; public class SAXHandler extends DefaultHandler { Stack tags = null; @Override public void startDocument() throws SAXException { tags=new Stack(); } @Override public void endDocument() throws SAXException { while(!tags.isEmpty()){ System.out.println(tags.peek()); tags.pop(); } tags=null; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if("students".equals(qName)){ System.out.println(attributes.getValue("class")+"--人數-"+attributes.getValue("count")); } tags.push(qName);//壓入棧 } @Override public void endElement(String uri, String localName, String qName) throws SAXException { tags.pop();//取出棧頂元素 } @Override public void characters(char[] ch, int start, int length) throws SAXException { String tag=(String) tags.peek();//檢視棧頂元素,但不移除 if("name".equals(tag)){ System.out.println("name==="+new String(ch,start,length)); } if("age".equals(tag)){ System.out.println("age==="+new String(ch,start,length)); } } }
三、JDOM
JDOM
優點:①是基於樹的處理XML的Java API,把樹載入在記憶體中
②沒有向下相容的限制,因此比DOM簡單
③速度快,缺陷少
④具有SAX的JAVA規則
缺點:①不能處理大於記憶體的文件
②JDOM表示XML文件邏輯模型。不能保證每個位元組真正變換。
③針對例項文件不提供DTD與模式的任何實際模型。
④不支援與DOM中相應遍歷包
最適合於:JDOM具有樹的便利,也有SAX的JAVA規則。在需要平衡時使用
JDOM package xmlParse; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; 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; public class TestJDOM { /** * @param args */ public static void main(String[] args) { buildXmlByJDOM(); parseXmlByJDOM(); } public static String buildXmlByJDOM(){ Document doc=new Document(); Element root=new Element("students"); root.setAttribute("count", "3"); root.setAttribute("class", "一班"); doc.setRootElement(root); root.addContent(new Element("student").addContent(new Element("name").setText("小明")) .addContent(new Element("age").setText("10"))); root.addContent(new Element("student").addContent(new Element("name").setText("小汪")) .addContent(new Element("age").setText("11"))); root.addContent(new Element("student").addContent(new Element("name").setText("小兵")) .addContent(new Element("age").setText("12"))); ByteArrayOutputStream out=new ByteArrayOutputStream(); XMLOutputter putter=new XMLOutputter(); try { putter.output(doc, out); putter.output(doc, new FileOutputStream("students.xml")); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return out.toString(); } public static void parseXmlByJDOM(){ long begintime=System.currentTimeMillis(); File f=new File("students.xml"); SAXBuilder builder=new SAXBuilder(); try { Document doc=builder.build(new FileInputStream(f)); Element root=doc.getRootElement(); System.out.println(root.getAttributeValue("class")+"-人數:--"+root.getAttributeValue("count")); List list=root.getChildren("student"); for(int i=0;i<list.size();i++){ Element ele=(Element)list.get(i); System.out.println("第"+(i+1)+"個學生"); System.out.println(ele.getChildText("name")+"---"+ele.getChildText("age")); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println("sax解析時間(毫秒)"+(System.currentTimeMillis()-begintime)); } }
四、DOM4J
DOM4J 是一個非常非常優秀的Java XML API,具有效能優異、功能強大和極端易用使用的特點,同時它也是一個開放原始碼的軟體。如今你可以看到越來越多的 Java 軟體都在使用 DOM4J 來讀寫 XML,特別值得一提的是連 Sun 的 JAXM 也在用 DOM4J。
DOM4J
package xmlParse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class TestDom4J {
/**
* @param args
*/
public static void main(String[] args) {
buildXmlByDOM4J();
paserXmlByDOM4J();
}
public static void buildXmlByDOM4J(){
Document doc=DocumentHelper.createDocument();
doc.setXMLEncoding("UTF-8");
Element root=doc.addElement("students");
root.addAttribute("class", "一班").addAttribute("count", "3");
Element student=root.addElement("student");
student.addElement("name").setText("小明");
student.addElement("age").setText("10");
student=root.addElement("student").addAttribute("position", "班長");
student.addElement("name").setText("小汪");
student.addElement("age").setText("11");
student=root.addElement("student");
student.addElement("name").setText("小兵");
student.addElement("age").setText("12");
String xmlStr=doc.asXML();
try {
OutputFormat format=OutputFormat.createPrettyPrint();
XMLWriter writer=new XMLWriter(new FileWriter(new File("students.xml")),format);
writer.setEscapeText(false);
writer.write(xmlStr);
writer.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
public static void paserXmlByDOM4J(){
long begintime=System.currentTimeMillis();
SAXReader reader=new SAXReader();
try {
Document doc=reader.read(new FileInputStream(new File("students.xml")));
Element root=doc.getRootElement();
System.out.println(root.attributeValue("class")+"--人數--"+root.attributeValue("count"));
/* List<Node> list=root.selectNodes("student");//需要引入jaxen-1.1.1.jar
for(int i=0,len=list.size();i<len;i++){
Node node=(Node)list.get(i);
System.out.println(node.selectSingleNode("name").getText()+"---"+node.selectSingleNode("age").getStringValue());
}*/
Iterator it=root.elementIterator();
Element ele;
while(it.hasNext()){
ele=(Element)it.next();
//System.out.println(ele.selectSingleNode("name").getText()+"---"+ele.selectSingleNode("age").getText());
System.out.println(ele.elementText("name")+"---"+ele.elementText("age"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
System.out.println("sax解析時間(毫秒)"+(System.currentTimeMillis()-begintime));
}
}