Java解析XML的四種方法

XML文件解析方法  java

XML在不一樣的語言裏解析方式都是同樣的,只不過實現的語法不一樣而已。基本的解析方式有兩種,一種叫SAX,另外一種叫DOM。SAX是基於事件流的解析,DOM是基於XML文檔樹結構的解析。假設咱們XML的內容和結構以下: node

<?xml version="1.0" encoding="UTF-8"?>   
  1. <employees>   
  2.   <employee>   
  3.     <name>ddviplinux</name>   
  4.     <sex>m</sex>   
  5.     <age>30</age>   
  6.   </employee>   
  7. </employees>  

本文實現DOM與SAX的XML文檔生成與解析。 

首先定義一個操做XML文檔的接口XmlDocument 它定義了XML文檔的創建與解析的接口。 linux

  1. package com.alisoft.facepay.framework.bean;  
  2.   
  3. /** 
  4.  *  
  5.  * @author hongliang.dinghl  
  6.  * 定義XML文檔創建與解析的接口 
  7.  */  
  8. public interface XmlDocument {  
  9.     /** 
  10.      * 創建XML文檔  
  11.      * @param fileName 文件全路徑名稱 
  12.      */  
  13.     public void createXml(String fileName);   
  14.   
  15.     /** 
  16.      * 解析XML文檔 
  17.      * @param fileName 文件全路徑名稱 
  18.      */  
  19.     public void parserXml(String fileName);  
  20. }  

1.DOM生成和解析XML文檔 程序員

爲 XML 文檔的已解析版本定義了一組接口。解析器讀入整個文檔,而後構建一個駐留內存的樹結構,而後代碼就可使用 DOM 接口來操做這個樹結構。優勢:整個文檔樹在內存中,便於操做;支持刪除、修改、從新排列等多種功能;缺點:將整個文檔調入內存(包括無用的節點),浪費時間和空間;使用場合:一旦解析了文檔還需屢次訪問這些數據;硬件資源充足(內存、CPU)。  編程

(1)DOM解析XML文檔所使用到的jar:dom.jar app

(2)DOM解析與建立XML文檔示例代碼 dom

package com.alisoft.facepay.framework.bean;  
  1.   
  2. import java.io.FileNotFoundException;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.PrintWriter;  
  6.   
  7. import javax.xml.parsers.DocumentBuilder;  
  8. import javax.xml.parsers.DocumentBuilderFactory;  
  9. import javax.xml.parsers.ParserConfigurationException;  
  10. import javax.xml.transform.OutputKeys;  
  11. import javax.xml.transform.Transformer;  
  12. import javax.xml.transform.TransformerConfigurationException;  
  13. import javax.xml.transform.TransformerException;  
  14. import javax.xml.transform.TransformerFactory;  
  15. import javax.xml.transform.dom.DOMSource;  
  16. import javax.xml.transform.stream.StreamResult;  
  17.   
  18. import org.w3c.dom.Document;  
  19. import org.w3c.dom.Element;  
  20. import org.w3c.dom.Node;  
  21. import org.w3c.dom.NodeList;  
  22. import org.xml.sax.SAXException;  
  23.   
  24. /** 
  25.  *  
  26.  * @author hongliang.dinghl DOM生成與解析XML文檔 
  27.  */  
  28. public class DomDemo implements XmlDocument {  
  29.     private Document document;  
  30.     private String fileName;  
  31.       
  32.     public void init() {  
  33.         try {  
  34.             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
  35.             DocumentBuilder builder = factory.newDocumentBuilder();  
  36.             this.document = builder.newDocument();  
  37.         } catch(ParserConfigurationException  e) {  
  38.             System.out.println(e.getMessage());  
  39.         }  
  40.     }  
  41.       
  42.     //建立一個xml文件  
  43.     public void createXml(String fileName) {  
  44.         Element root = this.document.createElement("employees");  //建立一個xml文件根節點  
  45.         this.document.appendChild(root); //把根節點加到xml文檔結構下面  
  46.         Element employee = this.document.createElement("employee"); //創過employee節點  
  47.         Element name = this.document.createElement("name"); //建立name節點  
  48.         name.appendChild(this.document.createTextNode("丁宏亮")); //建立一個內容,並把內容加到name節點下面  
  49.         employee.appendChild(name);  //把name加到employee下面  
  50.         Element sex = this.document.createElement("sex"); //建立軍一個sex節點  
  51.         sex.appendChild(this.document.createTextNode("m")); //建立一個性別添加到性別節點下面  
  52.         employee.appendChild(sex); //把性別添加到,人員節點下面  
  53.         Element age = this.document.createElement("age");   
  54.         age.appendChild(this.document.createTextNode("30"));   
  55.         employee.appendChild(age);   
  56.         root.appendChild(employee);   
  57.         TransformerFactory tf = TransformerFactory.newInstance();   
  58.         try {   
  59.             Transformer transformer = tf.newTransformer();   
  60.             DOMSource source = new DOMSource(document);   
  61.             transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");   
  62.             transformer.setOutputProperty(OutputKeys.INDENT, "yes");   
  63.             PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));    
  64.             StreamResult result = new StreamResult(pw);   
  65.             transformer.transform(source, result);   
  66.             System.out.println("生成XML文件成功!");   
  67.         } catch (TransformerConfigurationException e) {   
  68.             System.out.println(e.getMessage());   
  69.         } catch (IllegalArgumentException e) {   
  70.             System.out.println(e.getMessage());   
  71.         } catch (FileNotFoundException e) {   
  72.             System.out.println(e.getMessage());   
  73.         } catch (TransformerException e) {   
  74.             System.out.println(e.getMessage());   
  75.         }   
  76.   
  77.     }  
  78.   
  79.     //解釋一個XML文件  
  80.     public void parserXml(String fileName) {  
  81.         try {  
  82.             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
  83.             DocumentBuilder db = dbf.newDocumentBuilder();  
  84.             Document document = db.parse(fileName); // 讀取xml文件  
  85.             NodeList employees = document.getChildNodes();  
  86.   
  87.             for (int i = 0; i < employees.getLength(); i++) {  
  88.                 Node employee = employees.item(i);  
  89.                 NodeList employeeInfo = employee.getChildNodes();  
  90.                 for (int j = 0; j < employeeInfo.getLength(); j++) {  
  91.                     Node node = employeeInfo.item(j);  
  92.                     NodeList employeeMeta = node.getChildNodes();  
  93.                     for (int k = 0; k < employeeMeta.getLength(); k++) {  
  94.                         System.out.println(employeeMeta.item(k).getNodeName()  
  95.                                 + ":" + employeeMeta.item(k).getTextContent());  
  96.                     }  
  97.                 }  
  98.             }  
  99.   
  100.             System.out.println("解析完畢");  
  101.         } catch (FileNotFoundException e) {  
  102.             System.out.println(e.getMessage());  
  103.         } catch (ParserConfigurationException e) {  
  104.             System.out.println(e.getMessage());  
  105.         } catch (SAXException e) {  
  106.             System.out.println(e.getMessage());  
  107.         } catch (IOException e) {  
  108.             System.out.println(e.getMessage());  
  109.         }  
  110.     }   
  111.   
  112. }  

2.SAX生成和解析XML文檔

爲解決DOM的問題,出現了SAX。SAX ,事件驅動。當解析器發現元素開始、元素結束、文本、文檔的開始或結束等時,發送事件,程序員編寫響應這些事件的代碼,保存數據。優勢:不用事先調入整個文檔,佔用資源少;SAX解析器代碼比DOM解析器代碼小,適於Applet,下載。缺點:不是持久的;事件事後,若沒保存數據,那麼數據就丟了;無狀態性;從事件中只能獲得文本,但不知該文本屬於哪一個元素;使用場合:Applet;只需XML文檔的少許內容,不多回頭訪問;機器內存少; 編程語言

(1)SAX解析XML文檔所使用到的jar包:sax.jar ide

(2)SAX關健類的,類結構圖 性能

(3)SAX文檔解釋示例代碼

package com.alisoft.facepay.framework.bean;  
  1.   
  2. import java.io.BufferedOutputStream;  
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7. import java.io.PrintStream;  
  8. import org.xml.sax.Attributes;  
  9. import org.xml.sax.ContentHandler;  
  10. import org.xml.sax.ErrorHandler;  
  11. import org.xml.sax.InputSource;  
  12. import org.xml.sax.Locator;  
  13. import org.xml.sax.SAXException;  
  14. import org.xml.sax.SAXParseException;  
  15. import org.xml.sax.XMLReader;  
  16. import org.xml.sax.helpers.XMLReaderFactory;  
  17.   
  18. public class XMLParser {  
  19.     protected PrintStream output = new PrintStream(new BufferedOutputStream(  
  20.             new FileOutputStream(java.io.FileDescriptor.out), 128), true);  
  21.     // handler error info.  
  22.     protected PrintStream error = new PrintStream(new BufferedOutputStream(  
  23.             new FileOutputStream(java.io.FileDescriptor.err), 128), true);  
  24.   
  25.     public void parserXMLFile(String fileName) throws SAXException, IOException {  
  26.         XMLReader reader = XMLReaderFactory.createXMLReader();  
  27.         reader.setContentHandler(new MyContentHandler());  
  28.         reader.setErrorHandler(new MyErrorHandler());  
  29.         InputSource source = new InputSource(new FileInputStream(new File(  
  30.                 fileName)));  
  31.         reader.parse(source);  
  32.     }  
  33.   
  34.     class MyErrorHandler implements ErrorHandler {  
  35.   
  36.         public void error(SAXParseException exception) throws SAXException {  
  37.   
  38.             error.println(exception.getMessage());  
  39.         }  
  40.   
  41.         public void fatalError(SAXParseException exception) throws SAXException {  
  42.   
  43.             error.println(exception.getMessage());  
  44.         }  
  45.   
  46.         public void warning(SAXParseException exception) throws SAXException {  
  47.             output.println(exception.getMessage());  
  48.   
  49.         }  
  50.   
  51.     }  
  52.   
  53.     class MyContentHandler implements ContentHandler {  
  54.   
  55.         private StringBuffer buffer = new StringBuffer();  
  56.         private String key;  
  57.   
  58.         public void characters(char[] ch, int start, int length)  
  59.                 throws SAXException {  
  60.             buffer.append(ch, start, length); // 添加標記中間的內容  
  61.   
  62.         }  
  63.   
  64.         public void endDocument() throws SAXException {  
  65.   
  66.         }  
  67.   
  68.         public void endElement(String uri, String localName, String name)  
  69.                 throws SAXException {  
  70.             if (key.equals(localName)) {  
  71.                 output.print(buffer); // 輸出標記中間的內容  
  72.             }  
  73.             output.print("</" + localName + ">");  
  74.         }  
  75.   
  76.         public void endPrefixMapping(String prefix) throws SAXException {  
  77.         }  
  78.   
  79.         public void ignorableWhitespace(char[] ch, int start, int length)  
  80.                 throws SAXException {  
  81.         }  
  82.   
  83.         public void processingInstruction(String target, String data)  
  84.                 throws SAXException {  
  85.         }  
  86.   
  87.         public void setDocumentLocator(Locator locator) {  
  88.         }  
  89.   
  90.         public void skippedEntity(String name) throws SAXException {  
  91.         }  
  92.   
  93.         public void startDocument() throws SAXException // XML文檔開始讀取時調用  
  94.         {  
  95.             output.println("<xml version=\"1.0\" encoding=\"utf-8\"?>");  
  96.         }  
  97.   
  98.         public void startElement(String uri, String localName, String name,  
  99.                 Attributes atts) throws SAXException // 獲取標記開始信息  
  100.         {  
  101.             // uri is identifier of namespace  
  102.             // name-->prefix:localName  
  103.   
  104.             buffer.delete(0, buffer.length());  
  105.             key = localName;  
  106.   
  107.             output.print("<" + localName);  
  108.             for (int i = 0; i < atts.getLength(); i++) {  
  109.                 String attrName = atts.getLocalName(i);  
  110.                 String attrValue = atts.getValue(i);  
  111.                 output.print(" " + attrName + "=" + attrValue);  
  112.             }  
  113.             output.print(">" + "\r");  
  114.         }  
  115.   
  116.         public void startPrefixMapping(String prefix, String uri)  
  117.                 throws SAXException {  
  118.         }  
  119.     }  
  120.   
  121.     public static void main(String[] args) throws Exception, IOException {  
  122.         XMLParser parser = new XMLParser();  
  123.         parser.parserXMLFile("D:/testSpace/testPrj/src/xmlPackage/MyXml.xml"); // 解釋XML文件  
  124.     }  
  125. }  

(4)SAX生成XML文檔示例代碼(生成XML)
package com.alisoft.facepay.framework.bean;  
  1.   
  2. import java.io.FileOutputStream;  
  3. import java.io.StringWriter;  
  4. import javax.xml.transform.OutputKeys;  
  5. import javax.xml.transform.Result;  
  6. import javax.xml.transform.Transformer;  
  7. import javax.xml.transform.TransformerConfigurationException;  
  8. import javax.xml.transform.sax.SAXTransformerFactory;  
  9. import javax.xml.transform.sax.TransformerHandler;  
  10. import javax.xml.transform.stream.StreamResult;  
  11. import org.xml.sax.SAXException;  
  12. import org.xml.sax.helpers.AttributesImpl;  
  13.   
  14. public class XMLHandler {  
  15.     public String createXMLFile() {  
  16.         String xmlStr = null;  
  17.         try {  
  18.             Result resultXml = new StreamResult(new FileOutputStream(  
  19.                     "E://cities.xml"));  
  20.             StringWriter writerStr = new StringWriter();  
  21.             SAXTransformerFactory sff = (SAXTransformerFactory) SAXTransformerFactory  
  22.                     .newInstance();  
  23.             TransformerHandler th = sff.newTransformerHandler();  
  24.             Transformer transformer = th.getTransformer();  
  25.             transformer.setOutputProperty(OutputKeys.INDENT, "yes");  
  26.             transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");  
  27.             th.setResult(resultXml);  
  28.             th.startDocument();  
  29.             String four = "\n    ";  
  30.             String eight = "\n        ";  
  31.             AttributesImpl attr = new AttributesImpl();  
  32.             th.startElement("""""country", attr);  
  33.             th.characters(four.toCharArray(), 0, four.length());  
  34.   
  35.             th.startElement("""""china", attr);  
  36.   
  37.             th.characters(eight.toCharArray(), 0, eight.length());  
  38.   
  39.             th.startElement("""""city", attr);  
  40.             String bj = "Beijing";  
  41.             th.characters(bj.toCharArray(), 0, bj.length());  
  42.             th.endElement("""""city");  
  43.   
  44.             th.characters(eight.toCharArray(), 0, eight.length());  
  45.   
  46.             th.startElement("""""city", attr);  
  47.             String sh = "Shanghai";  
  48.             th.characters(sh.toCharArray(), 0, sh.length());  
  49.             th.endElement("""""city");  
  50.   
  51.             th.characters(four.toCharArray(), 0, four.length());  
  52.   
  53.             th.endElement("""""china");  
  54.             th.endElement("""""country");  
  55.             th.endDocument();  
  56.             xmlStr = writerStr.getBuffer().toString();  
  57.         } catch (TransformerConfigurationException e) {  
  58.             e.printStackTrace();  
  59.         } catch (SAXException e) {  
  60.             e.printStackTrace();  
  61.         } catch (Exception e) {  
  62.             e.printStackTrace();  
  63.         }  
  64.         return xmlStr;  
  65.     }  
  66.   
  67.     public static void main(String args[]) {  
  68.         XMLHandler xh = new XMLHandler();  
  69.         xh.createXMLFile();  
  70.     }  
  71. }  

生成的XML文檔:
 
 <?xml version="1.0" encoding="UTF-8" ?>  
  1. <country>  
  2.     <china>  
  3.         <city>Beijing</city>  
  4.         <city>Shanghai</city>  
  5.     </china>  
  6. </country>  

3.DOM4J生成和解析XML文檔

DOM4J 是一個很是很是優秀的Java XML API,具備性能優異、功能強大和極端易用使用的特色,同時它也是一個開放源代碼的軟件。現在你能夠看到愈來愈多的 Java 軟件都在使用 DOM4J 來讀寫 XML,特別值得一提的是連 Sun 的JAXM 也在用 DOM4J。

(1)Dom4j解析XML文檔所使用到的jar包:dom4j.jar

(2)Dom4j文檔解釋示例代碼

package com.alisoft.facepay.framework.bean;  
  1.   
  2. import java.io.File;  
  3. import java.io.FileWriter;  
  4. import java.io.IOException;  
  5. import java.io.Writer;  
  6. import java.util.Iterator;  
  7.   
  8. import org.dom4j.Document;  
  9. import org.dom4j.DocumentException;  
  10. import org.dom4j.DocumentHelper;  
  11. import org.dom4j.Element;  
  12. import org.dom4j.io.SAXReader;  
  13. import org.dom4j.io.XMLWriter;  
  14.   
  15. /** 
  16.  *  
  17.  * @author hongliang.dinghl Dom4j 生成XML文檔與解析XML文檔 
  18.  */  
  19. public class Dom4jDemo implements XmlDocument {  
  20.   
  21.     // Dom4j建立Xml文檔  
  22.     public void createXml(String fileName) {  
  23.         Document document = DocumentHelper.createDocument(); // 建立一個文檔對象  
  24.         Element employees = document.addElement("employees"); // 在根節點添加元素  
  25.         Element employee = employees.addElement("employee"); // 在employees下添加子節點  
  26.         Element name = employee.addElement("name"); // 在employee下添加子節點  
  27.         name.setText("ddvip"); // 給name節點添加內容  
  28.         Element sex = employee.addElement("sex");  
  29.         sex.setText("m");  
  30.         Element age = employee.addElement("age");  
  31.         age.setText("29");  
  32.         try {  
  33.             Writer fileWriter = new FileWriter(fileName);  
  34.             XMLWriter xmlWriter = new XMLWriter(fileWriter);  
  35.             xmlWriter.write(document);  
  36.             xmlWriter.close();  
  37.         } catch (IOException e) {  
  38.   
  39.             System.out.println(e.getMessage());  
  40.         }  
  41.   
  42.     }  
  43.   
  44.     // Dom4j解釋Xml文檔  
  45.     public void parserXml(String fileName) {  
  46.         File inputXml = new File(fileName);  
  47.         SAXReader saxReader = new SAXReader();  
  48.         try {  
  49.             Document document = saxReader.read(inputXml);  
  50.             Element employees = document.getRootElement();  
  51.             for (Iterator i = employees.elementIterator(); i.hasNext();) {  
  52.                 Element employee = (Element) i.next();  
  53.                 for (Iterator j = employee.elementIterator(); j.hasNext();) { // 遍例節點  
  54.                     Element node = (Element) j.next();  
  55.                     System.out.println(node.getName() + ":" + node.getText());  
  56.                 }  
  57.   
  58.             }  
  59.         } catch (DocumentException e) {  
  60.             System.out.println(e.getMessage());  
  61.         }  
  62.         System.out.println("dom4j parserXml");  
  63.     }  
  64. }  

4.JDOM生成和解析XML

爲減小DOM、SAX的編碼量,出現了JDOM;優勢:20-80原則,極大減小了代碼量。使用場合:要實現的功能簡單,如解析、建立等,但在底層,JDOM仍是使用SAX(最經常使用)、DOM、Xanan文檔。

(1)JDOM解析XML文檔所使用到的jar包jdom.jar
(2)JDOM文檔解釋示例代碼

  1. package com.alisoft.facepay.framework.bean;  
  2.   
  3. import java.io.FileNotFoundException;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6. import java.util.List;  
  7.   
  8. import org.jdom.Document;  
  9. import org.jdom.Element;  
  10. import org.jdom.JDOMException;  
  11. import org.jdom.input.SAXBuilder;  
  12. import org.jdom.output.XMLOutputter;  
  13.   
  14. /** 
  15.  *  
  16.  * @author hongliang.dinghl JDOM 生成與解析XML文檔 
  17.  *  
  18.  */  
  19. public class JDomDemo implements XmlDocument {  
  20.   
  21.     public void createXml(String fileName) {  
  22.         Document document;  
  23.         Element root;  
  24.         root = new Element("employees");  
  25.         document = new Document(root);  
  26.         Element employee = new Element("employee");  
  27.         root.addContent(employee);  
  28.         Element name = new Element("name");  
  29.         name.setText("ddvip");  
  30.         employee.addContent(name);  
  31.         Element sex = new Element("sex");  
  32.         sex.setText("m");  
  33.         employee.addContent(sex);  
  34.         Element age = new Element("age");  
  35.         age.setText("23");  
  36.         employee.addContent(age);  
  37.         XMLOutputter XMLOut = new XMLOutputter();  
  38.         try {  
  39.             XMLOut.output(document, new FileOutputStream(fileName));  
  40.         } catch (FileNotFoundException e) {  
  41.             e.printStackTrace();  
  42.         } catch (IOException e) {  
  43.             e.printStackTrace();  
  44.         }  
  45.     }  
  46.   
  47.     public void parserXml(String fileName) {  
  48.         SAXBuilder builder = new SAXBuilder(false);  
  49.         try {  
  50.             Document document = builder.build(fileName);  
  51.             Element employees = document.getRootElement();  
  52.             List employeeList = employees.getChildren();  
  53.             // 獲取employee節點  
  54.             for (int i = 0; i < employeeList.size(); i++) {  
  55.                 Element employee = (Element) employeeList.get(i);  
  56.                 List employeeInfo = employee.getChildren();  
  57.                 // 獲取employee節點下面的全部子節點  
  58.                 for(int j = 0; j < employeeInfo.size(); j++) {  
  59.                     Element info = (Element)employeeInfo.get(j);  
  60.                     System.out.println(info.getName() + ":" + info.getValue());  
  61.                 }  
  62.             }  
  63.         } catch (JDOMException  e) {  
  64.             System.out.println(e.getMessage());  
  65.         } catch (IOException e) {  
  66.             System.out.println(e.getMessage());  
  67.         }  
  68.     }  

比較

1)DOM4J性能最好,連Sun的JAXM也在用DOM4J.目前許多開源項目中大量採用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置文件。若是不考慮可移植性,那就採用DOM4J.

2)JDOM和DOM在性能測試時表現不佳,在測試10M文檔時內存溢出。在小文檔狀況下還值得考慮使用DOM和JDOM.雖然JDOM的開發者已經說明他們指望在正式發行版前專一性能問題,可是從性能觀點來看,它確實沒有值得推薦之處。另外,DOM還是一個很是好的選擇。DOM實現普遍應用於多種編程語言。它仍是許多其它與XML相關的標準的基礎,由於它正式得到W3C推薦(與基於非標準的Java模型相對),因此在某些類型的項目中可能也須要它(如在JavaScript中使用DOM)。

3)SAX表現較好,這要依賴於它特定的解析方式-事件驅動。一個SAX檢測即將到來的XML流,但並無載入到內存(固然當XML流被讀入時,會有部分文檔暫時隱藏在內存中)。

相關文章
相關標籤/搜索