SAX解析XML出現特殊字符


import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SaxParseService extends DefaultHandler{
    private List<Book> books = null;
    private Book book = null;
    private String preTag = null;//作用是記錄解析時的上一個節點名稱
    /**
     * 特殊字符數量很多時方法1顯然不實用此時可用轉義來實現 
     * &lt; <   
     * &gt; >   
     * &amp; &
     * &apos; '
     * &quot; " 
     * 即將xml中的特殊文檔全部替換為轉義字符
     * 如<name><thinking in java ><name>變成<name>&lt;thinking in java&gt;<name>。 
     * 但是對於這種情況解析過程會發生變化不是一次性解析<thinking in java >
     * 而是分三步先解析&lt;然后是thinking in java然后是&gt;
     * 因此要注意想要獲得<name>中數據必須要用StringBuffer將這三部分加起來。
     * 
     */
    StringBuffer sb = new StringBuffer();
    
    public List<Book> getBooks(InputStream xmlStream) throws Exception{
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        SaxParseService handler = new SaxParseService();
        parser.parse(xmlStream, handler);
        return handler.getBooks();
    }
    
    public List<Book> getBooks(){
        return books;
    }
    
    @Override
    public void startDocument() throws SAXException {
        books = new ArrayList<Book>();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        sb.delete(0, sb.length());  //清除字符內容
        if("book".equals(qName)){
            book = new Book();
            book.setId(Integer.parseInt(attributes.getValue(0)));
        }
        preTag = qName;//將正在解析的節點名稱賦給preTag
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if("book".equals(qName)){
            books.add(book);
            book = null;
        }
        preTag = null;/**當解析結束時置為空。這里很重要,例如,當圖中畫3的位置結束后,會調用這個方法
        ,如果這里不把preTag置為null,根據startElement(....)方法,preTag的值還是book,當文檔順序讀到圖
        中標記4的位置時,會執行characters(char[] ch, int start, int length)這個方法,而characters(....)方
        法判斷preTag!=null,會執行if判斷的代碼,這樣就會把空值賦值給book,這不是我們想要的。*/
    }
    
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if(preTag!=null){
//            String content = new String(ch,start,length);
            sb.append(ch,start,length);//字符相加
            String content =sb.toString();
            if("name".equals(preTag)){
                book.setName(content);
            }else if("price".equals(preTag)){
                book.setPrice(Float.parseFloat(content));
            }
        }
    }
    
}

 

public class Book {
    private int id;
    private String name;
    private float price;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
    @Override
    public String toString(){
        return this.id+":"+this.name+":"+this.price;
    }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book id="12">
        <name>&lt;thing in java ></name>
        <price>45.0</price> 
    </book>
    <book id="15">
        <name>Spring in Action</name>
        <price>39.0</price>
    </book>
</books>

采用JUNIT4測試

public class Test {
     @org.junit.Test
     public void testSAX() throws Throwable{  
            SaxParseService sax = new SaxParseService();  
            InputStream input = this.getClass().getClassLoader().getResourceAsStream("book.xml");  
            List<Book> books = sax.getBooks(input);  
            for(Book book : books){  
                System.out.println(book.getName());  
            }  
        }} 
     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM