java和android中sax解析xml
阿新 • • 發佈:2019-02-06
學習安卓sax解析xml時,想用java寫一個解析某個xml檔案的Handler,程式碼如下:
具體實現邏輯和在安卓裡寫的handler差不多,檔案也是同一個檔案,但是始終沒有輸出,於是開始除錯。首先是列印輸入流的內容,和檔案一字不差,沒毛病。接著列印nodeName,發現nodeName為空字元,很奇怪啊,於是再列印這兩個方法中的localName: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); } } }
@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;
}
終於成功解析xml!@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); } }