1.Android中三種XML的解析方式,分別爲Dom,Sax,Pull,其中Pull的解析方式最優java
2.Dom,Sax,Pull解析方式的區別node
(1).Dom解析方式:ide
首先一會兒加載整個文檔而後再挨個節點解析,費流量性能
優勢:對於處理大文檔,以及能力強的CPU性能比較快fetch
缺點:對於處理能力不夠強的CPU一會兒可能受不了,就像一我的一口先吃下一個大西瓜,再來嚼.ui
(2).Sax解析方式:url
SAX是事件驅動型解析方式spa
雖然說是事件驅動型的和PULL差很少,但沒有像pull那樣提供next接口,想向下繼續解析就向下,沒有靈活性,死板,包括獲得數據也是用模板弄好,對於特殊的數據組裝還要用變量控制。調試
sax是選擇性的解析,他是解析符合條件的內容。code
手動中止:
解析完須要的東西后就拋異常吧,好比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; }