1.Android中三种XML的解析方式,分别为Dom,Sax,Pull,其中Pull的解析方式最优
2.Dom,Sax,Pull解析方式的区别
(1).Dom解析方式:
首先一下子加载整个文档然后再挨个节点解析,费流量
优点:对于处理大文档,以及能力强的CPU性能比较快
缺点:对于处理能力不够强的CPU一下子可能受不了,就像一个人一口先吃下一个大西瓜,再来嚼.
(2).Sax解析方式:
SAX是事件驱动型解析方式
虽说是事件驱动型的和PULL差不多,但没有像pull那样提供next接口,想向下继续解析就向下,没有灵活性,死板,包括得到数据也是用模板弄好,对于特殊的数据组装还要用变量控制。
sax是选择性的解析,他是解析符合条件的内容。
手动停止:
解析完需要的东西后就抛异常吧,比如throw new SAXException("已拿到数据,中断解析!!!");
(3).Pull的解析方式:
Pull驱动型解析方式,加载时不把所有的节点都加载到解析机里,只是去一个一个节点去查找,如果是一个节点而且需要这个节点就取出来,不像DOM,不管你要不要都放在解析机里,要拿就拿,不拿就算了.,减少流量的使用
3.综上觉得Pull解析方式最优,通过调试代码发现,解析同一个XML文件,pull解析方式花的时间最少.
核心代码如下:
//DOM解析方式
private List<River> fetchRiverFromXmlByDom(String fileName) { long startTime = System.currentTimeMillis(); List<River> rivers = new ArrayList<River>(); // 加载xml文档的工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); InputStream inputStream = null; try { DocumentBuilder builder = factory.newDocumentBuilder(); // 加入文件流 inputStream = getAssets().open(fileName); // 转化为decument文档对象 Document document = builder.parse(inputStream); // 获得最根节点 Element root = document.getDocumentElement(); // 通过tag获得所有根节点下面的节点 NodeList nodeList = root.getElementsByTagName(riverStr); // 得到根节点下面有多少个节点 int noteListSize = nodeList.getLength(); // 声明river对象,river类中包含所有的节点string River river = null; for (int i = 0; i < noteListSize; i++) { river = new River(); // 获得节点元素 Element element = (Element) nodeList.item(i); // 设置通过属性名得到的节点元素 river.setName(element.getAttribute(nameStr)); river.setLength(Integer.parseInt(element.getAttribute(lengthStr))); // 通过tag名得到所有节点,再取得第一个节点(因为只有一个节点,如果这里面还有节点得再来一个类似的循环) Element introTag = (Element) element.getElementsByTagName(introductionStr).item(0); river.setIntroduction(introTag.getFirstChild().getNodeValue()); Element imageUrlTag = (Element) element.getElementsByTagName(imageurlStr).item(0); river.setImageurl(imageUrlTag.getFirstChild().getNodeValue()); // 收集所有的节点到这个集合里 rivers.add(river); } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } Log.d(T, "exec fetchRiverFromXmlByDom use time = " + (System.currentTimeMillis() - startTime)); return rivers; }
SAX解析方式:
private List<River> fetchRiverFormXmlBySAX(String fileName) { long startTime = System.currentTimeMillis(); List<River> rivers = null; SAXParserFactory factory = SAXParserFactory.newInstance(); InputStream inputStream = null; try { //得到解析机 SAXParser parser = factory.newSAXParser(); //读取数据 XMLReader reader = parser.getXMLReader(); //取数据的句柄 MySaxHandler handler = new MySaxHandler(); reader.setContentHandler(handler); inputStream = getAssets().open(fileName); reader.parse(new InputSource(inputStream)); rivers = handler.getRivers(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Log.d(T, "exec fetchRiverFormXmlBySAX use time = " + (System.currentTimeMillis() - startTime)); return rivers; } private class MySaxHandler extends DefaultHandler { private List<River> rivers = null; private boolean isRiver = false; private boolean isIntrocduce = false; private boolean isImageUrl = false; private River river = null; private String TAG = "MySaxHandler"; public MySaxHandler() { rivers = new ArrayList<River>(); } @Override public void startDocument() throws SAXException { super.startDocument(); Log.d(TAG, "### startDocument"); } @Override public void endDocument() throws SAXException { super.endDocument(); Log.d(TAG, "### endDocument"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); String tagName = localName.length() > 0 ? localName : qName; if (tagName.equals(riverStr)) { isRiver = true; river = new River(); river.setName(attributes.getValue(nameStr)); river.setLength(Integer.parseInt(attributes.getValue(lengthStr))); } if (isRiver) { if (tagName.equals(introductionStr)) { isIntrocduce = true; } else if (tagName.equals(imageurlStr)) { isImageUrl = true; } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); // Log.d(TAG, "### endElement uri=" + uri + " localName=" + // localName + " qName=" + qName); String tagName = localName.length() != 0 ? localName : qName; if (tagName.equals(riverStr)) { isRiver = false; rivers.add(river); } if (isRiver) { if (tagName.equals(introductionStr)) { isIntrocduce = false; } else if (tagName.equals(imageurlStr)) { isImageUrl = false; } } } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); if (isIntrocduce) { river.setIntroduction(river.getIntroduction() == null ? "" : river .getIntroduction() + new String(ch, start, length)); } else if (isImageUrl) { river.setImageurl(river.getImageurl() == null ? "" : river.getImageurl() + new String(ch, start, length)); } } public List<River> getRivers() { return rivers; } }
Pull解析方式:
private List<River> fetchRiverFormXmlByPull(String fileName) { long startTime = System.currentTimeMillis(); List<River> rivers = new ArrayList<River>(); River river = null; InputStream inputStream = null; // 获得解析机对象 XmlPullParser xmlPullParser = Xml.newPullParser(); try { // 得到文件流 inputStream = getAssets().open(fileName); xmlPullParser.setInput(inputStream, "utf-8"); // 获得命名空间(必须调用,否则会抛出异常) xmlPullParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); // Returns the type of the current event (START_TAG, END_TAG, TEXT, // etc.) int eventType = xmlPullParser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { //开始节点<xxx> case XmlPullParser.START_TAG: String tag = xmlPullParser.getName(); //Log.d(T, "START_TAG:" + tag); if (tag.equalsIgnoreCase(riverStr)) { river = new River(); river.setName(xmlPullParser.getAttributeValue(null, nameStr)); river.setLength(Integer.parseInt(xmlPullParser.getAttributeValue(null, lengthStr))); } else if (river != null) { if (tag.equalsIgnoreCase(introductionStr)) { river.setIntroduction(xmlPullParser.nextText()); } else if (tag.equalsIgnoreCase(imageurlStr)) { river.setImageurl(xmlPullParser.nextText()); } } break; //结束节点</xx> case XmlPullParser.END_TAG: //Log.d(T, "END_TAG:" + xmlPullParser.getName()); if (xmlPullParser.getName().equalsIgnoreCase(riverStr) && river != null) { rivers.add(river); river = null; } break; default: break; } eventType = xmlPullParser.next(); } } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Log.d(T, "exec fetchRiverFormXmlByPull use time = " + (System.currentTimeMillis() - startTime)); return rivers; }