您的位置:首页 > 其它

XML解析

2015-06-01 15:10 441 查看
现在在android平台上可以有三种对xml文件的解析方式,分别是DOM、SAX、PULL,他们各有有优缺点,如下:

1 Dom解析是将xml文件全部载入,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件;从全部载入这点可知这种方式比较消耗内存。

DOM是文档对象模型解析,构建文档的分层语法结构,在内存中建立DOM树,DOM树的节点以对象的形式来标识,文档解析文成以后,文档的整个DOM树都会放在内存中。

2 SAX解析器是基于事件处理的,需要从头到尾把XML文档扫描一遍,在扫描的过程中,每次遇到一个语法结构时,就会调用这个特定语法结构的事件处理程序,向应用程序发送一个事件。

3 PULL解析器的运行方式和SAX解析器很相似,它提供了类似的事件,如:开始元素和结束元素,使用parser,next() 可以进入下一个元素并且触发相应的事件,事件将作为代码被发送,因此可以使用一个switch来对事件进行选择,然后进行相应的处理。当开始解析元素的时候,调用parser.nextText()方法可以获得下一个Text类型的元素。

相对而言,使用PULL来解析比SAX要写的代码少很多,使用比较简单。

PULL的特点:

1)、简单的结构:一个接口、一个例外、一个工厂组成的PULL解析器

2)、简单易用:PULL解析器只有一个重要的方法next方法,他被用来检索下一个事件,而它只有5个常用的属性:

          1、STARTDOCUMENT

          2、START_TAG

          3、TEXT

          4、END_TAG

          5、END_DOCUMENT

下面结合实例来理解上面的理论知识:

1 要解析的xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id = "23">
<name>NEwii</name>
<age>21</age>
</person>
<person id = "20">
<name>WiiWill</name>
<age>25</age>
</person>
</persons>


解析方式:

1 DOM解析

public void testDOMgetPersons() throws Throwable{
InputStream inStream = this.getClass().getClassLoader().
getResourceAsStream("wangjialin.xml");
List<Person> persons = DOMPersonService.getPersons(inStream);
for(Person person : persons){
Log.i(TAG, person.toString());
}
}
下面是具体的DOM解析类DOMPersonService.java

package com.wangjialin.service;

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.wangjialin.domain.Person;

public class DOMPersonService {
public static List<Person> getPersons(InputStream inStream) throws Exception{
List<Person> persons = new ArrayList<Person>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inStream);
Element root = document.getDocumentElement();
NodeList personNodes = root.getElementsByTagName("person");
for(int i=0; i < personNodes.getLength() ; i++){
Element personElement = (Element)personNodes.item(i);
int id = new Integer(personElement.getAttribute("id"));
Person person = new Person();
person.setId(id);
NodeList childNodes = personElement.getChildNodes();
for(int y=0; y < childNodes.getLength() ; y++){
if(childNodes.item(y).getNodeType()==Node.ELEMENT_NODE){
if("name".equals(childNodes.item(y).getNodeName())){
String name = childNodes.item(y).getFirstChild().getNodeValue();
person.setName(name);
}else if("age".equals(childNodes.item(y).getNodeName())){
String age = childNodes.item(y).getFirstChild().getNodeValue();
person.setAge(new Short(age));
}
}
}
persons.add(person);
}
inStream.close();
return persons;
}
}
2 SAX解析
public void testSAXGetPersons() throws Throwable{
InputStream inputStream = this.getClass().getClassLoader().
getResourceAsStream("wangjialin.xml");
SAXForHandler saxForHandler = new SAXForHandler();
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
saxParser.parse(inputStream, saxForHandler);
List<Person> persons = saxForHandler.getPersons();
inputStream.close();
for(Person person:persons){
Log.i(TAG, person.toString());
}
}
下面是事件处理类SAXForHandler.java
package com.wangjialin.service;

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

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

import android.util.Log;

import com.wangjialin.domain.Person;

public class SAXForHandler extends DefaultHandler {
private static final String TAG = "SAXForHandler";
private List<Person> persons;
private String perTag ;//通过此变量,记录前一个标签的名称。
Person person;//记录当前Person

public List<Person> getPersons() {
return persons;
}

//适合在此事件中触发初始化行为。
public void startDocument() throws SAXException {
persons = new ArrayList<Person>();
Log.i(TAG , "***startDocument()***");
}

public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if("person".equals(localName)){
for ( int i = 0; i < attributes.getLength(); i++ ) {
Log.i(TAG ,"attributeName:" + attributes.getLocalName(i)
+ "_attribute_Value:" + attributes.getValue(i));
person = new Person();
person.setId(Integer.valueOf(attributes.getValue(i)));
}
}
perTag = localName;
Log.i(TAG , qName+"***startElement()***");
}

public void characters(char[] ch, int start, int length) throws SAXException {
String data = new String(ch, start, length).trim();
if(!"".equals(data.trim())){
Log.i(TAG ,"content: " + data.trim());
}
if("name".equals(perTag)){
person.setName(data);
}else if("age".equals(perTag)){
person.setAge(new Short(data));
}
}

public void endElement(String uri, String localName, String qName)
throws SAXException {
Log.i(TAG , qName+"***endElement()***");
if("person".equals
4000
(localName)){
persons.add(person);
person = null;
}
perTag = null;
}

public void endDocument() throws SAXException {
Log.i(TAG , "***endDocument()***");
}
}


3 PULL解析

下面是PULL解析客户端调用:

public void testPullgetPersons() throws Throwable{
InputStream inStream = this.getClass().getClassLoader().getResourceAsStream("wangjialin.xml");
List<Person> persons = PullPersonService.getPersons(inStream);
for(Person person : persons){
Log.i(TAG, person.toString());
}
}
下面是使用PULL的方式保存person到XML文件的客户端调用:
public void testSave() throws Throwable{
File file = new File(this.getContext().getFilesDir(), "wangjialin.xml");
FileOutputStream outStream = new FileOutputStream(file);
List<Person> persons = new ArrayList<Person>();
persons.add(new Person(90, "wangjialin", (short)13));
persons.add(new Person(35, "jialingege", (short)23));
persons.add(new Person(78, "Android", (short)33));
PullPersonService.save(persons, outStream);
}


以下是实现PULL解析及使用PULL的方式保存对象到xml文件的实现类:
package com.wangjialin.service;

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

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import android.util.Xml;

import com.wangjialin.domain.Person;

public class PullPersonService {
public static void save(List<Person> persons, OutputStream outStream) throws Exception{
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(outStream, "UTF-8");
serializer.startDocument("UTF-8", true);
serializer.startTag(null, "persons");
for(Person person : persons){
serializer.startTag(null, "person");
serializer.attribute(null, "id", person.getId().toString());
serializer.startTag(null, "name");
serializer.text(person.getName());
serializer.endTag(null, "name");

serializer.startTag(null, "age");
serializer.text(person.getAge().toString());
serializer.endTag(null, "age");

serializer.endTag(null, "person");
}
serializer.endTag(null, "persons");
serializer.endDocument();
outStream.flush();
outStream.close();
}

public static List<Person> getPersons(InputStream inStream) throws Exception{
Person person = null;
List<Person> persons = null;
XmlPullParser pullParser = Xml.newPullParser();
pullParser.setInput(inStream, "UTF-8");
int event = pullParser.getEventType();//触发第一个事件
while(event!=XmlPullParser.END_DOCUMENT){
switch (event) {
case XmlPullParser.START_DOCUMENT:
persons = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG:
if("person".equals(pullParser.getName())){
int id = new Integer(pullParser.getAttributeValue(0));
person = new Person();
person.setId(id);
}
if(person!=null){
if("name".equals(pullParser.getName())){
person.setName(pullParser.nextText());
}
if("age".equals(pullParser.getName())){
person.setAge(new Short(pullParser.nextText()));
}
}
break;

case XmlPullParser.END_TAG:
if("person".equals(pullParser.getName())){
persons.add(person);
person = null;
}
break;
}
event = pullParser.next();
}
return persons;
}
}

完整源代码工程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  XML解析