DOM:文檔驅動。DOM在解析文件以前把整個文檔裝入內存,處理大型文件時其性能不好,是因爲DOM的樹結構所形成的,此結構佔用的內存較多。 SAX:事件驅動型的XML解析方式。順序讀取XML文件,不須要一次所有裝載整個文件。當遇到像文件開頭,文檔結束,或者標籤開頭與標籤結束時,會觸發一個事件,用戶經過在其回調事件中寫入處理代碼來處理XML文件,適合對XML的順序訪問,且是隻讀的 StAX採用流模型中的拉模型分析方式。提供基於指針和基於迭代器兩種方式的支持。 優勢: 一、接口簡單,使用方便。 二、採用流模型分析方式,有較好的性能。 缺點: 一、單向導航,不支持XPath,很難同時訪問同一文檔的不一樣部分。
DOM解析:
java
1、DOM4j中,得到Document對象的方式有三種: 1.讀取XML文件,得到document對象 SAXReader reader = new SAXReader(); Document document = reader.read(new File("csdn.xml")); 2.解析XML形式的文本,獲得document對象. String text = "<csdn></csdn>"; Document document = DocumentHelper.parseText(text); 3.主動建立document對象. Document document = DocumentHelper.createDocument(); //建立根節點 Element root = document.addElement("csdn"); 2、節點對象操做的方法: 1.獲取文檔的根節點. Element root = document.getRootElement(); 2.取得某個節點的子節點. Element element=node.element(「四大名著"); 3.取得節點的文字 String text=node.getText(); 4.取得某節點下全部名爲「csdn」的子節點,並進行遍歷. List nodes = rootElm.elements("csdn"); for (Iterator it = nodes.iterator(); it.hasNext();) { Element elm = (Element) it.next(); // do something } 5.對某節點下的全部子節點進行遍歷. for(Iterator it=root.elementIterator();it.hasNext();){ Element element = (Element) it.next(); // do something } 6.在某節點下添加子節點 Element elm = newElm.addElement("朝代"); 7.設置節點文字. elm.setText("明朝"); 8.刪除某節點.//childElement是待刪除的節點,parentElement是其父節點 parentElement.remove(childElment); 9.添加一個CDATA節點.Element contentElm = infoElm.addElement("content");contentElm.addCDATA(「cdata區域」); 3、將文檔寫入XML文件 1.文檔中全爲英文,不設置編碼,直接寫入的形式. XMLWriter writer = new XMLWriter(new FileWriter("ot.xml")); writer.write(document); writer.close(); 2.文檔中含有中文,設置編碼格式寫入的形式. OutputFormat format = OutputFormat.createPrettyPrint();// 建立文件輸出的時候,自動縮進的格式 format.setEncoding("UTF-8");//設置編碼 XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format); writer.write(document); writer.close(); 4、字符串與XML的轉換 1.將字符串轉化爲XML String text = "<csdn> <java>Java班</java></csdn>"; Document document = DocumentHelper.parseText(text); 2.將文檔或節點的XML轉化爲字符串. SAXReader reader = new SAXReader(); Document document = reader.read(new File("csdn.xml")); Element root=document.getRootElement(); String docXmlText=document.asXML(); String rootXmlText=root.asXML(); Element memberElm=root.element("csdn"); String memberXmlText=memberElm.asXML();
dom4j解析示例:node
package dom4j; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.junit.Test; public class Demo01 { @Test public void test() throws Exception { // 建立saxReader對象 SAXReader reader = new SAXReader(); // 經過read方法讀取一個文件 轉換成Document對象 Document document = reader.read(new File("src/dom4j/sida.xml")); //獲取根節點元素對象 Element node = document.getRootElement(); //遍歷全部的元素節點 listNodes(node); // 獲取四大名著元素節點中,子節點名稱爲紅樓夢元素節點。 Element element = node.element("紅樓夢"); //獲取element的id屬性節點對象 Attribute attr = element.attribute("id"); //刪除屬性 element.remove(attr); //添加新的屬性 element.addAttribute("name", "做者"); // 在紅樓夢元素節點中添加朝代元素的節點 Element newElement = element.addElement("朝代"); newElement.setText("清朝"); //獲取element中的做者元素節點對象 Element author = element.element("做者"); //刪除元素節點 boolean flag = element.remove(author); //返回true代碼刪除成功,不然失敗 System.out.println(flag); //添加CDATA區域 element.addCDATA("紅樓夢,是一部愛情小說."); // 寫入到一個新的文件中 writer(document); } /** * 把document對象寫入新的文件 * * @param document * @throws Exception */ public void writer(Document document) throws Exception { // 緊湊的格式 // OutputFormat format = OutputFormat.createCompactFormat(); // 排版縮進的格式 OutputFormat format = OutputFormat.createPrettyPrint(); // 設置編碼 format.setEncoding("UTF-8"); // 建立XMLWriter對象,指定了寫出文件及編碼格式 // XMLWriter writer = new XMLWriter(new FileWriter(new // File("src//a.xml")),format); XMLWriter writer = new XMLWriter(new OutputStreamWriter( new FileOutputStream(new File("src//a.xml")), "UTF-8"), format); // 寫入 writer.write(document); // 當即寫入 writer.flush(); // 關閉操做 writer.close(); } /** * 遍歷當前節點元素下面的全部(元素的)子節點 * * @param node */ public void listNodes(Element node) { System.out.println("當前節點的名稱::" + node.getName()); // 獲取當前節點的全部屬性節點 List<Attribute> list = node.attributes(); // 遍歷屬性節點 for (Attribute attr : list) { System.out.println(attr.getText() + "-----" + attr.getName() + "---" + attr.getValue()); } if (!(node.getTextTrim().equals(""))) { System.out.println("文本內容::::" + node.getText()); } // 當前節點下面子節點迭代器 Iterator<Element> it = node.elementIterator(); // 遍歷 while (it.hasNext()) { // 獲取某個子節點對象 Element e = it.next(); // 對子節點進行遍歷 listNodes(e); } } /** * 介紹Element中的element方法和elements方法的使用 * * @param node */ public void elementMethod(Element node) { // 獲取node節點中,子節點的元素名稱爲西遊記的元素節點。 Element e = node.element("西遊記"); // 獲取西遊記元素節點中,子節點爲做者的元素節點(能夠看到只能獲取第一個做者元素節點) Element author = e.element("做者"); System.out.println(e.getName() + "----" + author.getText()); // 獲取西遊記這個元素節點 中,全部子節點名稱爲做者元素的節點 。 List<Element> authors = e.elements("做者"); for (Element aut : authors) { System.out.println(aut.getText()); } // 獲取西遊記這個元素節點 全部元素的子節點。 List<Element> elements = e.elements(); for (Element el : elements) { System.out.println(el.getText()); } } }
SAX解析:
c++
主要是要複寫DefaultHandler類,而後在類中調用便可dom
package saxXml; import java.io.IOException; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; public class SAXxml { public static void main(String[] args) throws ParserConfigurationException, SAXException{ //建立解析工廠 SAXParserFactory factory=SAXParserFactory.newInstance(); //獲得解析器 SAXParser parse=factory.newSAXParser(); //獲得讀取器 XMLReader reader= parse.getXMLReader(); //設置內容處理器 BeanListHandler beanListHandler=new BeanListHandler(); reader.setContentHandler(beanListHandler); //讀取文檔內容: try { reader.parse("src/saxXml/bookXml.xml"); //reader.parse("\\src\\saxXml\\bookXml.xml"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } List<Book> list= beanListHandler.getBooks(); System.out.println("list 數量"+list.size()); //遍歷獲取取得的內容 for(int i=0;i<list.size();i++){ System.out.println(i); Book book=list.get(i); System.out.print("name:"+book.getName()); System.out.print("author"+book.getAuthor()); System.out.print("price"+book.getPrice()); System.out.println(); } } } BeanListHandler類: package saxXml; import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; //將XML中的每本書封裝到Book中 public class BeanListHandler extends DefaultHandler{ private List books=new ArrayList(); private String currentTag; private Book book; public List getBooks(){ return books; } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.println("字符串"+currentTag+new String(ch,start,length)+";"); if("name".equals(currentTag)){ book.setName(new String(ch,start,length)); book.getName(); // System.out.println("姓名"); // System.out.println("tag:"+book.getName()); } if("author".equals(currentTag)){ book.setAuthor(new String(ch,start,length)); } if("price".equals(currentTag)){ book.setPrice(new String(ch,start,length)); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if(qName.equals("book")){ books.add(book); System.out.println("name:"+book.getName()); book=null; } } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //+uri+";"+localName+";" +attributes currentTag=qName; System.out.println("startElement:"+qName+";"+currentTag); if("book".equals(qName)){ book=new Book(); System.out.println("start"); } } } XML文件: <?xml version="1.0" encoding="UTF-8"?> <bookstore> <book> <name>java</name> <author>minyi</author> <price>cpp</price> </book> <book> <name>c++</name> <author>zhouhui</author> <price>stl</price> </book> </bookstore>
STAX解析:ide
SAX也是基於事件處理xml文檔,但倒是用推模式解析,解析器解析完整個xml文檔後,才產生解析事件,而後推給程序去處理這些事件。SAX中解析器是工做主體,而事件處理器是由解析器驅動的,若是解析文檔過程當中產生問題,則剩餘的全部文檔就沒法處理。 StAX使用拉模式,解析器首先將XML文檔全部的事件所有取出,而後經過處理程序處理這些事件。StAX中處理器是工做主體,若是解析文檔過程當中產生問題,只會影響到出問題的部分,其他部分處理不受影響 package staxXml; import java.io.FileInputStream; import java.io.InputStream; import java.util.Calendar; import java.util.Date; import java.util.Scanner; import java.util.Timer; import java.util.TimerTask; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.StartDocument; import javax.xml.stream.events.XMLEvent; public class Scheduler { private static final String TAG_ITEM = "item"; private static final String TAG_TASK = "task"; private static final String TAG_STRATEGY = "strategy"; private static final String STRATEGE_REPEAT = "repeat"; private static final String STRATEGE_DAILY = "daily"; private static final String TAG_REPEATFREQ = "repeatFreq"; private static final String TAG_DAILYRUNTIME = "dailyRuntime"; void readConfig(){ //建立解析工廠 XMLInputFactory inputFactory= XMLInputFactory.newInstance(); inputFactory.setProperty("javax.xml.stream.isCoalescing", true);//避免讀取多行數據時出現問題 //簡歷一個新的eventReader InputStream in = new FileInputStream(Global.SERVICE_CONFIGURE_FILE); XMLEventReader eventReader = inputFactory.createXMLEventReader(in); // One specification String task = null; String strategy = null; Integer freq = null;// by second // for daily job Date firstTime = null; Calendar calendar = Calendar.getInstance(); while(eventReader.hasNext()){ XMLEvent event=(XMLEvent) eventReader.next(); //判斷其實開始仍是結束標籤 if(event.isStartElement()){ StartDocument startElement= (StartDocument) event.asStartElement(); //判斷其是哪一個標籤 if (((EndElement) startElement).getName().getLocalPart().equals(TAG_ITEM)) { /* Iterator<Attribute> attributes = startElement.getAttributes(); while (attributes.hasNext()) { attributes.next(); // skip } */ } if (event.asStartElement().getName().getLocalPart().equals(TAG_TASK)) { event = eventReader.nextEvent(); task = event.asCharacters().getData(); continue; } if (event.asStartElement().getName().getLocalPart().equals(TAG_STRATEGY)) { event = eventReader.nextEvent(); strategy = event.asCharacters().getData(); continue; } if (event.asStartElement().getName().getLocalPart().equals(TAG_REPEATFREQ)) { event = eventReader.nextEvent(); freq = Integer.parseInt(event.asCharacters().getData()); continue; } if (event.asStartElement().getName().getLocalPart().equals(TAG_DAILYRUNTIME)) { event = eventReader.nextEvent(); // hour:min:sec Scanner scanner = new Scanner(event.asCharacters().getData()); scanner.useDelimiter(":"); int hour = scanner.nextInt(); int minute = scanner.nextInt(); int second = scanner.nextInt(); // firstTime (today) calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); calendar.set(Calendar.SECOND, second); firstTime = calendar.getTime(); continue; } } //若是是結束標籤 if(event.isEndElement()){ EndElement endElement=event.asEndElement(); if(endElement.getName().getLocalPart().equals(TAG_ITEM)){ Timer timer=new Timer(); if(strategy.equals(STRATEGE_REPEAT)) { Class<?> clz = Class.forName(Global.TASK_PACKAGE_PREFIX + task); TimerTask ctr = (TimerTask)clz.newInstance(); timer.schedule(ctr, 0, freq*1000); } else if(strategy.equals(STRATEGE_DAILY)){ Class<?> clz = Class.forName(Global.TASK_PACKAGE_PREFIX + task); TimerTask ctr = (TimerTask)clz.newInstance(); timer.schedule(ctr, firstTime, Global.PERIOD_DAY); } else { _logger.error("Unexpected configuration option "+ strategy +" in " + Global.SERVICE_CONFIGURE_FILE); } } } } } }
參考文章:性能
dom4j: http://blog.csdn.net/redarmy_chen/article/details/12969219 ui
stax: http://blog.csdn.net/chjttony/article/details/6125123 編碼