android dom解析跟pull解析区别,[Android] android平台下sax,dom,pull解析方式性能比较

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 fetchRiverFromXmlByDom(String fileName) {

long startTime = System.currentTimeMillis();

List rivers = new ArrayList();

// 加载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 

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 fetchRiverFormXmlBySAX(String fileName) {

long startTime = System.currentTimeMillis();

List 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 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();

}

@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 getRivers() {

return rivers;

}

}

Pull解析方式:

private List fetchRiverFormXmlByPull(String fileName) {

long startTime = System.currentTimeMillis();

List rivers = new ArrayList();

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) {

//开始节点

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;

//结束节点

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值