您的位置:首页 > 其它

Dom、Sax、Pull解析xml文件

2016-06-22 21:18 537 查看

使用以上三种方式解析xml文件

在android开发中,经常用到去解析xml文件,常见的解析xml的方式有一下三种:SAX、Pull、Dom解析方式。

DOM,它的特点是一次全部加载,如果对于数据量小的情况下,它的效率还可以,如果XML文件很大的情况下,速度就会慢起来。

SAX,方式比较符合我们日常思维方式,容易上手,但是它直接把文档调入内存中,比较耗内存。

PULL,用法大致和sax一样,但它可以在程序中控制,想解析到哪里就可以停止到哪里,Android中更推荐使用pull解析。

接下来举个简单的例子,使用以上三种方式解析:

<books>
<book>
<price>50</price>
<name>三国演义</name>
<author age="23">罗贯中</author>
</book>
<book>
<price>60</price>
<name>红楼梦</name>
<author age="59">曹雪芹</author>
</book>
<book>
<price>40</price>
<name>水浒传</name>
<author age="12">施耐庵</author>
</book>
</books>


将以上文件存放在assets文件夹下进行读取解析:

首先定义接口类实现方法:

package com.example.dom.parser;

import java.io.InputStream;
import java.util.List;

import com.example.dom.beans.Book;

/**
* 解析接口
*/
public interface IParser {

/**
* 解析xml文件
*
* @param is
*            xml文件输入流
* @return book列表
*/
public List<Book> parse(InputStream is);

}


第一种:DOM解析:

package com.example.dom.parser;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.example.dom.beans.Book;

public class DomParser implements IParser {

@Override
public List<Book> parse(InputStream is) {
// 创建list用于保存解析出来的book
List<Book> list = new ArrayList<Book>();
try {
// 首先,我们创建一个工厂对象,注意:它的创建方式,不是new出来的
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 通过咱们的工厂对象,创建出DocumentBuilder
DocumentBuilder docBuilder = factory.newDocumentBuilder();
// 将流转成Document对象
Document doc = docBuilder.parse(is);
// 从Document对象中,获取根结点
Element rootElement = doc.getDocumentElement();
// 从根结点中获取所有的book
NodeList books = rootElement.getElementsByTagName("book");
// 遍历book列表
for (int i = 0; i < books.getLength(); i++) {
Book book = new Book();
//获取单个book结点
Node bookNode = books.item(i);
//获取book结点下的所有子结点
NodeList childNodes = bookNode.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
//取一个子结点
Node n = childNodes.item(j);
// 获取结点名称
String nodeName = n.getNodeName();
if ("name".equalsIgnoreCase(nodeName)) {
// 判断是name结点时,把结点的值设置给book对象的name属性
String name = n.getFirstChild().getNodeValue();
book.setName(name);
}else if("author".equalsIgnoreCase(nodeName)){
// 判断是author结点时,把结点的值设置给book对象的author属性
String author = n.getFirstChild().getNodeValue();
book.setAuthor(author);
//取age属性值
NamedNodeMap attributes = n.getAttributes();
Node namedItem = attributes.getNamedItem("age");
String propertyValue = namedItem.getNodeValue();

}else if("price".equalsIgnoreCase(nodeName)){
// 判断是price结点时,把结点的值设置给book对象的price属性
String price = n.getFirstChild().getNodeValue();
book.setPrice(price);
}
}
list.add(book);
}

} catch (Exception e) {
e.printStackTrace();
}

return list;
}

}


第二种SAX解析:

package com.example.dom.parser;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import com.example.dom.beans.Book;

import android.util.Log;

/**
* <p>
* Description:sax解析类,使用后置标签,即endElement方法实现
* </p>
*
*/
public class SaxParser implements IParser {

@Override
public List<Book> parse(InputStream is) {
// 创建list用于保存解析出来的book
List<Book> list = new ArrayList<Book>();
try {
// 创建SAXParserFactory对象,用于生成saxParser
SAXParserFactory factory = SAXParserFactory.newInstance();
// 通过SAXParserFactory创建parser解析器
SAXParser parser = factory.newSAXParser();
// 从解析器中获取reader
XMLReader reader = parser.getXMLReader();
SaxHandler handler = new SaxHandler();
reader.setContentHandler(handler);
reader.parse(new InputSource(is));
return handler.getList();

} catch (Exception e) {
e.printStackTrace();
}

return list;
}

/**
* <p>
* Description:解析处理类
* </p>
*/
static class SaxHandler extends DefaultHandler {

private Book book;
private String value; // 用于记录文本信息
private List<Book> list;// 用于保存解析完的book对象

@Override
public void startDocument() throws SAXException {
// 文档开始的时候,去创建list
list = new ArrayList<Book>();
book = null;
}

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
Log.e("", "==startElement==" + qName);
// 如果是book标签的开始,那么我们需要创建book对象
if ("book".equalsIgnoreCase(qName)) {
book = new Book();
}
if ("author".equals(qName)) {
Log.e("", "==author==" + attributes.getValue("age"));
}
}

@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
}

@Override
public void endElement(String uri, String localName, String qName) throws SAXException {

// 为book对象设置属性值
if ("name".equals(qName)) {
book.setName(value);
} else if ("author".equalsIgnoreCase(qName)) {
book.setAuthor(value);
} else if ("price".equalsIgnoreCase(qName)) {
book.setPrice(value);
} else if ("book".equalsIgnoreCase(qName)) {
// 如果是book标签的结束,那么将book对象添加到list中
list.add(book);
}
}

@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// 获取文本信息
value = new String(ch, start, length);
}

public List<Book> getList() {
return list;
}

}

}


第三种 PULL解析:

package com.example.dom.parser;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;

import com.example.dom.beans.Book;

import android.content.res.XmlResourceParser;
import android.util.Log;
import android.util.Xml;

/**
* <p>Description:</p>
*
*/
public class PullParser implements IParser {

// 创建list用于保存解析出来的book
private List<Book> list = null;

@Override
public List<Book> parse(InputStream is) {
try {
XmlPullParser xmlParser = Xml.newPullParser();
xmlParser.setInput(is, "utf-8");
Book book = null;
int eventType = xmlParser.getEventType();

while (eventType != XmlResourceParser.END_DOCUMENT) {
String tagName = xmlParser.getName(); //获取当前标签
switch (eventType) {
case XmlResourceParser.START_DOCUMENT:
list = new ArrayList<Book>();
break;
case XmlResourceParser.START_TAG:
// 如果是book标签的开始,那么我们需要创建book对象
if ("book".equalsIgnoreCase(tagName)) {
book = new Book();
} else if ("name".equals(tagName)) {
book.setName(xmlParser.nextText());
} else if ("author".equalsIgnoreCase(tagName)) {

Log.e("", "==age=" + xmlParser.getAttributeValue(null, "age"));
book.setAuthor(xmlParser.nextText());
} else if ("price".equalsIgnoreCase(tagName)) {
book.setPrice(xmlParser.nextText());
}
break;
case XmlResourceParser.END_TAG:
if ("book".equalsIgnoreCase(tagName)) {
Log.e("", "===" + book);
list.add(book);
book = null;
}
break;
}
eventType = xmlParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}

}


bean类:

package com.example.dom.beans;

import java.io.Serializable;

import com.thoughtworks.xstream.annotations.XStreamAlias;

/**
* 图书实体类
*/
@XStreamAlias("book")
public class Book implements Serializable {

private static final long serialVersionUID = 1L;
private String name;// 书名
private String author;// 作者
private String price;// 价格

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public String getPrice() {
return price;
}

public void setPrice(String price) {
this.price = price;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name).append("\t").append(author).append("\t").append(price).append("元");
return sb.toString();
//      return "Book [name=" + name + ", author=" + author + ", price=" + price + "]";
}

}


返回时调用的bean类:

package com.example.dom.beans;

import java.util.List;

import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias("books")
public class Books {

private List<Book> book;
}


MainActivity中实现:

package com.example.dom;

import java.util.List;

import com.example.dom.beans.Book;
import com.example.dom.parser.DomParser;
import com.example.dom.parser.IParser;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {

private ListView mLv;

/* (non-Javadoc)
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mLv = (ListView) findViewById(R.id.lv);
try {
IParser parser = new DomParser();
//          IParser parser = new SaxParser();
//          IParser parser = new PullParser();

List<Book> list = parser.parse(getAssets().open("book.xml"));
ArrayAdapter<Book> adapter = new ArrayAdapter<Book>(this, android.R.layout.simple_list_item_1, list);
mLv.setAdapter(adapter);

} catch (Exception e) {
e.printStackTrace();
}
}

}


以上是使用三种解析方式对简单的xml进行了解析案例,希望能够帮助大家。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  xml