您的位置:首页 > 移动开发 > Android开发

【Android学习】XML文本的三种解析方式(通过搭建本地的Web项目提供XML文件)

2014-01-04 15:46 901 查看
XML为一种可扩展的标记语言,是一种简单的数据存储语言,使用一系列简单的标记来描述。

一、SAX解析

  即Simple API for XML,以事件的形式通知程序,对Xml进行解析。

  1、首先在Web项目中发布一个XML文档,名字为persons.xml,具体内容为: 

<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="1">
<name>周杰伦</name>
<age>20</age>
</person>
<person id="2">
<name>小明</name>
<age>21</age>
</person>

</persons>


  2、SAX解析的流程主要如下:

  

  通过创建SAXParserFactory对象获得一个实例,然后再通过工厂获得一个SaxParser,依靠SaxParser的parse方法,完成解析,其中parse方法的参数为一个InputStream类和一个DefaultHandler类,defaultHandler需     要重写

    SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parse = spf.newSAXParser();
Myhandler handler = new Myhandler("person");
parse.parse(is, handler);
list = handler.getList();


  

  3、重写处理类DefaultHandler。

  

  

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

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

public class Myhandler extends DefaultHandler {

List<HashMap<String, String>> list = null;// 存储所有的解析对象
String currentTag = null; // 正在解析的标签
String currentValue = null; // 正在解析元素的值
String nodename = null; // 正在解析节点名称
HashMap<String, String> map = null;// 存储单个解析的完整对象

public Myhandler(String nodename) {
this.nodename = nodename;
}

public List<HashMap<String, String>> getList() {
return list;
}

@Override
// 读到第一个开始标签的时候触发
public void startDocument() throws SAXException {

list = new ArrayList<HashMap<String, String>>();
}

@Override
// 当遇到所要解析的节点名称时触发
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {

if (qName.equals(nodename)) {
map = new HashMap<String, String>();

}

if (attributes != null && map != null) {
for (int i = 0; i < attributes.getLength(); i++) {
map.put(attributes.getQName(i), attributes.getValue(i));
}
}

currentTag = qName;

}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equals(nodename)) {
list.add(map);
map = null;
}
super.endElement(uri, localName, qName);
}

@Override
// 处理xml文件读取到的内容
public void characters(char[] ch, int start, int length)
throws SAXException {

if (currentTag != null && map != null) {
currentValue = new String(ch, start, length);
if (currentValue != null && !currentValue.trim().equals("")
&& !currentValue.trim().equals("\n")) {
map.put(currentTag, currentValue);
}

}

currentTag = null;
currentValue = null;
}

}


  

  

  

  4、通过自定义的HttpUtils类,从服务器获取数据,以流的形式返回,也就是XML文档的输入流,这里不再给出,关于获得服务器数据的三种方式下次会下次更新。

  5、最后通过返回的List<Map<String,String>> 获得了XML文档的所需要的内容,需要提到的是,我在这里是需要解析person节点,于是只有qName等于person时候才会开始解析。

二、PULL解析

  类似于SAX方式,程序以“拉取”的方式对Xml进行解析。

  1、与SAX解析类似,但比SAX解析容易,需要JAR包,下载地址:

http://pan.baidu.com/s/1hq3JnKg


  2、首先通过XMLPullFactory创建一个工厂,然后再由工厂创建一个XMLPullParser对象,由对象进行相关处理。

  3、通过对eventType进行XML文件的节点解析,获得数据,并存放在List中进行返回。

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

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

public class PullXmlHandler {

public static List<Person> parseXml(InputStream is, String encode)
throws Exception {
List<Person> list = null;
Person p = null;
try {
XmlPullParserFactory xmlPullF = XmlPullParserFactory.newInstance();
XmlPullParser parser = xmlPullF.newPullParser();
parser.setInput(is, encode);
int eventType = parser.getEventType();
  
        //如果还没到文档结束节点就一直循环
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
list = new ArrayList<Person>();
break;

case XmlPullParser.START_TAG:
if (parser.getName().equals("person")) {
p = new Person();
if (parser.getAttributeCount() != 0) {
p.setId(parser.getAttributeValue(0));
}
} else if (parser.getName().equals("name")) {
p.setName(parser.nextText());
} else if (parser.getName().equals("age")) {
p.setAge(parser.nextText());
}
break;
case XmlPullParser.END_TAG:
if (parser.getName().equals("person")) {
list.add(p);
p = null;
}
break;
default:
break;
}
        //进行下次循环
                 eventType = parser.next();

}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}

} 


三、DOM解析

  “文档对象模型”方式,解析完的Xml将生成一个树状结构的对象。

  1、DOM解析相对前两种比较麻烦,代码如下:

  

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.Node;
import org.w3c.dom.NodeList;

import com.xml.httputils.http_post;

public class DomService {

public DomService() {
}

public static List<Person> parseXML(InputStream is) throws Exception {
List<Person> list = new ArrayList<Person>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
// 获得节点
Element element = document.getDocumentElement();
NodeList nodeList = element.getElementsByTagName("person");
for (int i = 0; i < nodeList.getLength(); i++) {
Element personElement = (Element) nodeList.item(i);
Person p = new Person();
p.setId(personElement.getAttribute("id"));
NodeList personList = personElement.getChildNodes();
for (int j = 0; j < personList.getLength(); j++) {
if (personList.item(j).getNodeType() == Node.ELEMENT_NODE) {
if ("name".equals(personList.item(j).getNodeName())) {
p.setName(personList.item(j).getFirstChild()
.getNodeValue());
} else if ("age".equals(personList.item(j).getNodeName())) {
p.setAge(personList.item(j).getFirstChild()
.getNodeValue());
}
}
}
list.add(p);
}
return list;

}

public static void main(String[] args) throws Exception {
DomService dom = new DomService();
List<Person> ps = dom.parseXML(http_post.getXMLStream());
for (Person p : ps) {
System.out.println(p);
}
}
}


总结:

  对于小内存的设备,尤其是Android设备,使用PULL解析或者SAX解析远优于DOM解析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: