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;
}