Android解析XML文件的三方法
2011-10-27 19:12
441 查看
除了可以使用 SAX和DOM解析XML文件,大家也可以使用Android内置的Pull解析器解析XML文件。 Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值。
public class PullService {
public static List<Person> readXML(InputStream inputStream) throws IOException{
XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(inputStream, "UTF-8");
int eventType = parser.getEventType();
Person currentPerson = null;
List<Person> persons = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT://文档开始事件,可以进行数据初始化处理
persons = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG://开始元素事件
String name = parser.getName();
if (name.equalsIgnoreCase("person")) {
currentPerson = new Person();
currentPerson.setId(new Integer(parser.getAttributeValue(null, "id")));
} else if (currentPerson != null) {
if (name.equalsIgnoreCase("name")) {
currentPerson.setName(parser.nextText());// 如果后面是Text节点,即返回它的值
} else if (name.equalsIgnoreCase("age")) {
currentPerson.setAge(new Short(parser.nextText()));
}
}
break;
case XmlPullParser.END_TAG://结束元素事件
if (parser.getName().equalsIgnoreCase("person") && currentPerson != null) {
persons.add(currentPerson);
currentPerson = null;
}
break;
}
eventType = parser.next();
}
inputStream.close();
return persons;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//将内容保存至XML文件
public static String writeXML(List<Person> persons, Writer writer){
XmlSerializer serializer = Xml.newSerializer();
try {
serializer.setOutput(writer);
serializer.startDocument("UTF-8", true);
//第一个参数为命名空间,如果不使用命名空间,可以设置为null
serializer.startTag("", "persons");
for (Person person : persons){
serializer.startTag("", "person");
serializer.attribute("", "id", person.getId().toString());
serializer.startTag("", "name");
serializer.text(person.getName());
serializer.endTag("", "name");
serializer.startTag("", "age");
serializer.text(person.getAge().toString());
serializer.endTag("", "age");
serializer.endTag("", "person");
}
serializer.endTag("", "persons");
serializer.endDocument();
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
生成的person.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="23">
<name>liming</name>
<age>30</age>
</person>
<person id="20">
<name>lili</name>
<age>25</age>
</person>
</persons>
DOM解析XML文件
DOM解析XML文件时,会将XML文件的所有内容以文档树方式存放在内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来是比较直观的,并且在某些方面比基于SAX的实现更加简单。但是,因为DOM需要将XML文件的所有内容以文档树方式存放在内存中,所以内存的消耗比较大,特别对于运行Android的移动设备来说,因为设备的资源比较宝贵,所以建议还是采用SAX来解析XML文件,当然,如果XML文件的内容比较小采用DOM也是可行的。
public class DOMXmlReader {
public static List<Person> XMLReader(InputStream inStream)throws Exception{
List<Person> persons=new ArrayList<Person>();
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
try{
DocumentBuilder builder=factory.newDocumentBuilder();
Document document= builder.parse(inStream);
Element root=document.getDocumentElement();
NodeList items=root.getElementsByTagName("person");//得到所有person节点
for(int i=0;i<items.getLength();i++){
Person person=new Person();
Element personNode=(Element)items.item(i);
person.setId(new Integer(personNode.getAttribute("id")));
//获取person节点下的所有子节点(标签之间的空白节点和name/age元素)
NodeList childsNodes = personNode.getChildNodes();
for (int j = 0; j < childsNodes.getLength(); j++) {
Node node = (Node) childsNodes.item(j); //判断是否为元素类型
if(node.getNodeType() == Node.ELEMENT_NODE){
Element childNode = (Element) node;
//判断是否name元素
if ("name".equals(childNode.getNodeName())) {
//获取name元素下Text节点,然后从Text节点获取数据 person.setName(childNode.getFirstChild().getNodeValue());
} else if ("age".equals(childNode.getNodeName())) {
person.setAge(new Short(childNode.getFirstChild().getNodeValue()));
}
}
}
persons.add(person);
}
inStream.close();
}catch(Exception e){
e.printStackTrace();
}
return persons;
}
}
SAX是一种占用内存少且解析速度快的解析器,它采用的是事件启动,它不需要解析完整个文档,而是按照内容顺序 看文档某个部分是否符合xml语法,如果符合就触发相应的事件,所谓的事件就是些回调方法(callback),这些方法 定义在ContentHandler中,下面是其主要方法:
startDocument:当遇到文档的时候就触发这个事件 调用这个方法 可以在其中做些预处理工作。
startElement: (String namespaceURI,String localName,String qName,Attributes atts)当遇开始标签的时候就会触发这个方法。
endElement(String uri,String localName,String name):当遇到结束标签时触发这个事件,调用此法可以做些善后工作。
charachers(char [] ch,int start,int length):当遇到xml内容时触发这个方法,用new String(ch,start,length)可以接受内容。
下面是一个例子:
文件名称:person.xml
<?xml version="1.0" encoding="UTF-8"?> <persons> <person id="23"> <name>李明</name> <age>30</age> </person> <person id="20"> <name>李向梅</name> <age>25</age> </person> </persons>
public class SAXService {
public List<Person> personService(InputStream inStream)throws Exception{
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser parser=factory.newSAXParser();
PersonDefaultHandler handler=new PersonDefaultHandler();
parser.parse(inStream, handler);
inStream.close();
return handler.getPersons();
}
private final class PersonDefaultHandler extends DefaultHandler{
private List<Person> persons=null;
private Person currentPerson;
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
private String tagName=null;
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(tagName!=null){
String data =new String(ch,start,length);
if("name".equals(data)){
currentPerson.setName(data);
}else if("age".equals(data)){
currentPerson.setAge(Short.parseShort(data));
}
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if("person".equals(localName)){
persons.add(currentPerson);
currentPerson=null;
}
tagName=null;
}
@Override
public void startDocument() throws SAXException {
persons=new ArrayList<Person>();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attr) throws SAXException {
if("person".equals(localName)){
currentPerson=new Person();
currentPerson.setId(Integer.parseInt(attr.getValue("id")));
}
tagName=localName;
}
}
}
下面是测试类:
public class PersonTest extends AndroidTestCase {
private static final String TAG="PersonTest";
public void testSAXService()throws Throwable{
SAXService saxservice=new SAXService();
InputStream inStream=this.getClass().getClassLoader().getResourceAsStream("person.xml");
List <Person> persons=saxservice.personService(inStream);
for(Person p:persons){
Log.i(TAG,p.toString());
}
}
}
本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2010-11/29768p3.htm
相关文章推荐
- Android开发之DOM解析xml文件的方法
- Android学习札记10:用SAX解析XML文件时,当标签中出现换行符时可能出现读取内容为空的解决方法
- android XML文件解析之 SAX解析方法
- Android解析XML文件的三方法之DOM
- Android解析xml文件的方法:SAX
- Android中解析xml文件的方法
- Android解析XML文件的三方法之SAX
- Android 解析XML文件 XmlPullParser 方法
- Android解析XML文件升级APK的方法
- Android程序解析XML文件的方法及使用PULL解析XML案例
- android中Xml文件解析方法
- Android 使用Pull方法解析XML文件的方法
- android 解析XML文件方法之一---DOM
- Android 用Pull方法解析XML文件
- Android实战技巧:用Pull方法解析XML文件
- android用SAX解析xml文件时抛出org.apache.harmony.xml.ExpatParser$ParseException异常的解决方法
- Android开发--XML文件的解析的三种方法
- Android Studio ——Android 使用Pull方法解析XML文件的方法
- Android平台基于Pull方式对XML文件解析与写入方法详解
- Android实战技巧:用Pull方法解析XML文件