1. 程式人生 > >java和android中sax解析xml

java和android中sax解析xml

學習安卓sax解析xml時,想用java寫一個解析某個xml檔案的Handler,程式碼如下:

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParserFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class XMLParse {
    public static void main(String[] args){
        FileInputStream fis = null;
        try {
             fis = new FileInputStream("E:\\Apache24\\Apache\\htdocs\\get_data.xml");
             parseXMLWithSAX(fis);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    static void parseXMLWithSAX(InputStream is){
        try {
            ContentHandler handler = new ContentHandler();
            SAXParserFactory factory = SAXParserFactory.newInstance();
            XMLReader reader = factory.newSAXParser().getXMLReader();
            reader.setContentHandler(handler);
            reader.parse(new InputSource(is));
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

class ContentHandler extends DefaultHandler{
    StringBuilder id;
    StringBuilder name;
    StringBuilder version;
    String nodeName;
    @Override
    public void startDocument() throws SAXException {
        id = new StringBuilder();
        name = new StringBuilder();
        version = new StringBuilder();
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        nodeName = localName;
    }


    public void endElement(String uri, String localName, String qName) throws SAXException {
        if("app".equals(localName)) {
            System.out.println("id is " + id.toString().trim());
            System.out.println("name is " + name.toString().trim());
            System.out.println("version is " + version.toString().trim());
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if(nodeName.equals("id")) {
            id.append(ch, start, length);
        }else if(nodeName.equals("name")){
            name.append(ch, start, length);
        }else if(nodeName.equals("version")){
            version.append(ch, start, length);
        }
    }
}
具體實現邏輯和在安卓裡寫的handler差不多,檔案也是同一個檔案,但是始終沒有輸出,於是開始除錯。首先是列印輸入流的內容,和檔案一字不差,沒毛病。接著列印nodeName,發現nodeName為空字元,很奇怪啊,於是再列印這兩個方法中的localName:
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        nodeName = localName;
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if("app".equals(localName)) {
            System.out.println("id is " + id.toString().trim());
            System.out.println("name is " + name.toString().trim());
            System.out.println("version is " + version.toString().trim());
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }
    }

結果始終為空,問題找到。於是查閱資料,發現,這兩個方法還有一個qName引數,在java中節點名稱是qName,localName為空,安卓則相反!修改程式碼:
   @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        //nodeName = localName in Android
        nodeName = qName;
    }
   @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        //"app".equals("localName") in Android
        if("app".equals(qName)) {
            System.out.println("id is " + id.toString().trim());
            System.out.println("name is " + name.toString().trim());
            System.out.println("version is " + version.toString().trim());
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }
    }
終於成功解析xml!哭