需要有一个解析工厂,SAXParserFactory,通过解析工厂来获得解析器XMLReader,然后给解析器配置ContentHandler,最后通过parse来启动解析,其中有以下主要的方法:
startDocument:当遇到文档的时候就触发这个事件 调用这个方法 可以在其中做些预处理工作。
startElement: (String namespaceURI,String localName,String qName,Attributes atts)当遇开始标签的时候就会触发这个方法。
endElement(String uri,String localName,String name):当遇到结束标签时触发这个事件,调用此法可以做些善后工作。
charachers(char [] ch,int start,int length):当遇到xml内容时触发这个方法,用new String(ch,start,length)可以接受内容。
下面通过一个例子来说一下,之前做的版本更新的时候用过的,通过从服务器上获取当前版本信息文件,解析后和当前软件版本号比较来判断是否有新版本发布,这里只用到下载xml文件并解析。
下载部分代码:
1 public class HttpDownloader { 2 private URL url = null; 3 /** 4 * 根据URL下载文件,前提是这个文件当中的内容是文本,函数的返回值就是文件当中的内容 5 * 1.创建一个URL对象 6 * 2.通过URL对象,创建一个HttpURLConnection对象 3.得到InputStram 4.从InputStream当中读取数据 7 * @param urlStr 8 * @return 9 */ 10 public String download(String urlStr) { 11 StringBuffer sb = new StringBuffer(); 12 String line = null; 13 BufferedReader buffer = null; 14 try { 15 // 创建一个URL对象 16 url = new URL(urlStr); 17 // 创建一个Http连接 18 HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); 19 // 使用IO流读取数据 20 buffer = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); 21 while ((line = buffer.readLine()) != null) { 22 sb.append(line); 23 } 24 } catch (Exception e) { 25 e.printStackTrace(); 26 } finally { 27 try { 28 buffer.close(); 29 } catch (Exception e) { 30 e.printStackTrace(); 31 } 32 } 33 return sb.toString(); 34 } 35 }
返回一个string对象,就是服务器上的xml文件流。接着交给ContentHandler进行解析:
1 //xml是传进来的String值,versionInfos是保存留作回调的versionInfos对象 2 MyXMLHandler myXMLHandler = new MyXMLHandler(xml, versionInfos); 3 //解析成versionInfo对象 4 SAXParserFactory 5 saxParserFactory = SAXParserFactory.newInstance(); 6 try{ 7 XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader(); 8 xmlReader.setContentHandler(myXMLHandler); 9 xmlReader.parse(new InputSource(new StringReader(xml))); 10 } catch(Exception e){ 11 e.printStackTrace(); 12 }
这里,你要传递一个版本信息对象,解析后的值都保存在这里,下面最关键的就是这个MyXMLHandler类了,它是这样的:
1 public class VersionXMLHandler extends DefaultHandler { 2 private String xmlStr; 3 private List<VersionInfo> infos = null; 4 private VersionInfo versionInfo = null; 5 private String tagName = null; 6 /** 7 * 构造方法 8 * @param xmlStr 下载获取的xml串 9 * @param infos 回调用的infos 10 */ 11 public VersionXMLHandler(String xmlStr, List<VersionInfo> infos) { 12 super(); 13 this.xmlStr = xmlStr; 14 this.infos = infos; 15 } 16 public List<VersionInfo> getInfos() { 17 return infos; 18 } 19 public void setInfos(List<VersionInfo> infos) { 20 this.infos = infos; 21 } 22 @Override 23 public void characters(char[] ch, int start, int length) throws SAXException { 24 // TODO Auto-generated method stub 25 String temp = new String(ch, start, length); 26 if (tagName.equals("id")) { 27 versionInfo.setVersionId(temp); 28 } else if (tagName.equals("data")) { 29 versionInfo.setVersionData(temp); 30 } else if (tagName.equals("description")) { 31 versionInfo.setVersionDescription(temp); 32 } else if (tagName.equals("url")) { 33 versionInfo.setVersionUrl(temp); 34 } 35 } 36 @Override 37 public void endDocument() throws SAXException { 38 // TODO Auto-generated method stub 39 } 40 @Override 41 public void endElement(String uri, String localName, String qName) throws SAXException { 42 // TODO Auto-generated method stub 43 if (qName.equals("version")) { 44 infos.add(versionInfo); 45 } 46 tagName = ""; 47 } 48 @Override 49 public void startDocument() throws SAXException { 50 // TODO Auto-generated method stub 51 super.startDocument(); 52 } 53 @Override 54 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 55 // TODO Auto-generated method stub 56 this.tagName = localName; 57 if (tagName.equals("version")) { 58 versionInfo = new VersionInfo(); 59 } 60 } 61 }
它是这样工作的,首先startDocument(),这里不做什么事,只是开始了,接着会遇到startElement,当他的tagName值等于version时,会创建一个VsersionInfo对象,接着会遇到characters,对比各节点值,然后分别写入versionInfo对应的对象中,最后遇到</version>的时候,将完成的versionInfo写入List里,并设置tagName为空,留做下次用!
解析完成~~~~
来源:https://www.cnblogs.com/vtianyun/archive/2012/04/15/2450897.html