XML文件解析之--DOM與SAX

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中默認相同的編碼,輸出時選用字節流,配合格式化輸出器中規定的編碼,這樣就不會產生中文亂碼問題了。

相關文章
相關標籤/搜索