xml文件又稱‘可擴展性標記語言’,能夠對文檔和數據進行結構化處理,從而可以在部門、客戶和供應商之間進行交換,實現動態內容生成,企業集成和應用開發。web
咱們在進行web開發的時候離不開xml文件,xml文件無處不在,此次就爛討論一下xml經常使用的解析方法及其CRUD操做,歡迎你們交流指正。ide
咱們先來看看兩種解析方式的過程,比較一下他們的優劣之處。函數
SAX解析方式:它對xml文檔進行逐行掃描,一邊掃描一邊解析。當掃描到文檔(document)開始與結束、元素(element)開始與結束、文檔(document)結束等地方時通知事件處理函數,由事件處理函數作相應動做,而後繼續一樣的掃描,直至文檔結束。工具
DOM解析方式:DOM解析是W3C組織提供的標準,把全部內容一次性的裝載入內存,並構建一個駐留在內存中的樹狀結構,而後根據節點之間的關係來解析XML。性能
性能分析:this
1.SAX解析由於是逐行逐句掃描解析,比起DOM方式一次性裝在全部內容到內存中來講,效率來講應該更高一些。編碼
2.可是偏偏是SAX這種解析方式,註定使SAX解析不適合對XML文檔進行增刪改等操做。而DOM解析的增刪改操做相比之下就十分方便。spa
3.由於DOM解析式一次性裝在全部內容到內存中,因此若是用戶只須要其中一部份內容,DOM解析的方式的效率就大打折扣。code
綜上分析:sax解析更適合作部分信息的讀取操做,DOM解析更適合作XML文件的增刪改操做。orm
接下來咱們來看看它們的CRUD操做
xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE books SYSTEM "theBook.dtd"> <books> <book> <id>01</id> <name>魯濱遜漂流記</name> <price>33</price> </book> <book> <id>02</id> <name>鋼鐵是怎樣煉成的</name> <price>30</price> </book> </books>
對應的Bean類
public class Book { private String id; private String name; private String price; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } }
1.SAX解析:
流程:
1.獲取工廠實例;
2.獲得解析器;
3.獲得讀取器;
4.設置內容處理器;(SAX解析方式給咱們提供了不一樣的處理器接口以及父類,咱們能夠選擇繼承其中的父類或者實現接口進行內容處理)
在進行內容處理時,SAX提供了多種不一樣的方法,分別在文檔的開始和結尾,元素的開始和結尾等有事件,咱們須要在相應的地方重寫這些事件完成功能。
5.最後咱們將相應的對象模型設置屬性,將其存入list中,返回list。
解析實例:
public void saxFactory() throws ParserConfigurationException, SAXException, IOException{ //得到工廠實例 SAXParserFactory ft = SAXParserFactory.newInstance(); //獲得解析器 SAXParser sp = ft.newSAXParser(); //獲得讀取器 XMLReader reader = sp.getXMLReader(); //設置內容處理器 BeanListHandler handler = new BeanListHandler(); reader.setContentHandler(handler); reader.parse("src/Book.xml"); List <Book> list = handler.getList(); }
BeanListHandler類
class BeanListHandler extends DefaultHandler{ private List list = new ArrayList(); private String currentTag; private Book book; @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub if("name".equals(currentTag)){ String name = new String(ch,start,length); book.setName(name); } if("id".equals(currentTag)){ String id = new String(ch,start,length); book.setId(id); } if("price".equals(currentTag)){ String price = new String(ch,start,length); book.setPrice(price); } super.characters(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub if(qName.equals("book")){ list.add(book); book = null; } currentTag = null; super.endElement(uri, localName, qName); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { currentTag = qName; if("book".equals(currentTag)){ book = new Book(); } super.startElement(uri, localName, qName, attributes); } public List getList() { return list; } }
SAX解析:相對使用起來複雜一些,主要是實現步驟順序,以及相對應事件中填入實現功能代碼。
2.DOM解析:
DOM解析的實現代碼相對於前者就簡單易懂些
DOM解析中有多種解析工具,此處以DOM4j爲例
主要步驟:
1.得到讀取器
2.得到document對象
3.對相應的節點對象進行操做
讀取操做(獲取某個節點的值):
public void read() throws DocumentException{ SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/Book.xml")); Element root = document.getRootElement(); Element book = (Element)root.elements("book").get(1); System.out.println(book.element("name").getText()); }
增長操做:
public void add() throws DocumentException, IOException{ SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/Book.xml")); Element book = document.getRootElement().element("book"); book.addElement("author").setText("abc"); //格式化輸出器 OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); XMLWriter writer = new XMLWriter(new FileOutputStream("src/Book.xml"),format); writer.write(document); writer.close(); }
刪除操做:
public void delete() throws DocumentException, IOException{ SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/Book.xml")); Element root = document.getRootElement(); Element name = root.element("book").element("name"); name.getParent().remove(name); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); XMLWriter writer = new XMLWriter(new FileOutputStream("src/Book.xml"),format); writer.write(document); writer.close(); }
修改操做:
public void update() throws DocumentException, IOException{ SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/Book.xml")); Element root = document.getRootElement(); Element book = (Element) root.elements("book").get(1); book.element("name").setText("西遊記"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); XMLWriter writer = new XMLWriter(new FileOutputStream("src/Book.xml"),format); writer.write(document); writer.close(); }
!!此處須要注意:也許你們注意到了增刪改後面有五行代碼是同樣的。沒錯!由於須要對xml文件進行讀寫,因此也須要解決亂碼問題,解決亂碼問題有多種方法,此處只列舉這一種方法,建立格式化輸出器,規定其編碼和xml中默認相同的編碼,輸出時選用字節流,配合格式化輸出器中規定的編碼,這樣就不會產生中文亂碼問題了。