使用Pull和SAX解析XML格式数据
使用Pull和SAX解析XML格式数据1. Pull解析方式为了解析方便,这里使用了一个天气服务的api查询返回的xml文档,网址是这个:
有点略微尴尬的是这个网站被Chrome识别为有害网站,但本人多次打开表示应该没什么危害。。。 返回的xml大概是这样的: private void parseXMLWithPull(String xmlData) { try { // 首先是创建一个XmlPullParseFactory的实例 XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance(); // 借助这个实例得到XmlPullParser对象 XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser(); // 调用XmlPullParser的setInput()方法将服务器返回的XML数据设置进去,然后就可以解析了 xmlPullParser.setInput(new StringReader(xmlData)); // 通过getEventType()得到当前的解析事件,然后在一个while循环中不断的进行解析 // 如果当前的解析事件不等于XmlPullParser。END_DOCUMENT,说明解析工作还没有完成 // 调用next()方法获取下一个解析事件 int eventType = xmlPullParser.getEventType(); List<String> list = new ArrayList<>(); // 在while循环中,通过getName()来获取当前节点的名字,如果发现节点等于string // 就调用nextText()来获取节点的具体内容 while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { // 开始解析某个节点 case XmlPullParser.START_TAG: String name = xmlPullParser.getName(); if ("string".equals(name)) { String str = xmlPullParser.nextText(); list.add(str); } break; default: break; } eventType = xmlPullParser.next(); } showResponse(list); } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } 解析出来的文档是这样的: 2. SAX解析方式一般来说是需要新建一个继承自DefaultHandler的类,并重写父类的5个方法: public class ConTentHandler extends DefaultHandler { private String nodeName; private StringBuilder name; private List<String> list; // 在开始XML解析时调用 @Override public void startDocument() { name = new StringBuilder(); list = new ArrayList<>(); } // 在开始解析某个节点时调用 @Override public void startElement(String uri,String localName,String qNmae,Attributes attributes) { // 记录当前节点名 nodeName = localName; } // 在获取节点中内容时调用 @Override public void characters(char[] ch,int start,int length) { // 根据当前节点名判断将内容添加到那个StringBuilder中,这里只有一个StringBuilder if ("string".equals(nodeName)) { name.append(ch,start,length); list.add(name.toString()); } } // 在完成解析某个节点的时候调用 @Override public void endElement(String uri,String qNmae) { // 将StringBuilder清空 if ("string".equals(localName)) { name.setLength(0); //Log.v("string",name.toString().trim()); } } // 在完成整个XML解析时调用 @Override public void endDocument() throws SAXException { super.endDocument(); for (int i = 0; i < list.size(); i++){ System.out.println(list.get(i)); } } } 在这5个方法中,startElement(),characters(),endElement()是有参数的,从XML中解析出来的数据就会以参数的形式传入到这些方法中,此外在获取节点中的内容时,characters()会被多次调用,一些换行符也被当做内容解析出来,可以调用trim()方法来解决,trim()方法可以去掉字符串首尾的空格。 下面是来自
接下来只需要在MainActivity中增加一个parseXMLWithSAX方法就好了: private void parseXMLWithSAX(String xmlData) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); XMLReader reader = factory.newSAXParser().getXMLReader(); ContentHandler contentHandler = new ConTentHandler(); // 将编写好的ContentHandler的实例设置到XMLReader中 reader.setContentHandler(contentHandler); // 开始执行解析 reader.parse(new InputSource(new StringReader(xmlData))); } catch (Exception e) { e.printStackTrace(); } } Pull和SAX解析XML的区别首先我们知道SAX是事件驱动的,他不会将整个文档读入内存中再去解析,而是一边读取一边解析,所以说文档读取的过程也就是SAX的解析过程。但是虽然SAX解析XML不会将整个文档放进内存中,但是它会遍历文档中的所有节点所以如果我们只是需要文档开头或中间的一小部分内容,这个时候使用SAX就不划算了,因为我们不能停止解析。 SAX解析的工作方式是自动将时间推入到注册的时间处理器中进行处理,所以我们不能控制事件的处理的主动结束。 那么Pull呢?如果说SAX是一种“推”的解析方式,那么Pull就可以说是一种“拉”的解析方式,也就是说应用程序可以根据自己的需求来控制解析器的读取。Pull允许应用程序代码主动从解析器中获取事件,所以可以实现在解析出我们想要的数据后就终止解析。 总之呢,SAX和Pull都有解析速度快,占用内存少的优点,在工作方式上Pull是使用一个循环体,可以随时跳出来,而SAX是只要开始解析了那么久必须全部解析完成(SAX的强迫症无人能敌)。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |