Android对XML的解析

SAX,全称Simple API for XML,既是一种接口,也是一种软件包。它是一种XML解析的替代方法。SAX不同于DOM解析,它逐行扫描文档,一边扫描一边解析。

package com.xml.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.xml.domain.Person;

/**
* @ClassName: SAXForHandler
* @Description: SAX,全称Simple API for XML,既是一种接口,也是一种软件包。
* 它是一种XML解析的替代方法。SAX不同于DOM解析,它逐行扫描文档,一边扫描一边解析。
* 由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势。
* 
* 
* SAX的工作原理:
* 简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束
* 等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
* @author zhoujn
* @date 2015-4-4 下午9:19:54
* 
*/

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()***");
	}
	
	
	/* (非 Javadoc) 
	* <p>Title: startElement</p> 
	* <p>Description: </p> 
	* @param uri 命名空间
	* @param localName  标签名称
	* @param qName 带命名空间的标签名
	* @param attributes 存放改标签的所有属性
	* @throws SAXException 
	* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) 
	*/ 
	
	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()***");
	}
	
	/* (非 Javadoc) 
	* <p>Title: characters</p> 
	* <p>Description: </p> 
	* @param ch 当前读取到的TextNode字节数组
	* @param start 字节开始的位置,如果要读取全面,那就要从0开始
	* @param length 当前TextNode的长度
	* @throws SAXException 
	* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) 
	*/ 
	
	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(localName)){
			persons.add(person);
			person = null;
		}
		perTag = null;
	}

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



使用DOM解析XML

文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口。

package com.xml.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.xml.domain.Person;

public class DOMPersonService {
	public static List<Person> getPersons(InputStream inStream) throws Exception{
		List<Person> persons = new ArrayList<Person>();
		//DocumentBuilderFactory 该对象将创建DocumentBuilder
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		//DocumentBuilder将实际进行解析以创建Document
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse(inStream);
		
		Element root = document.getDocumentElement();//xml文档的根节点
		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;
	}
}

使用PULL解析XML:


使用Pull解析器读取XML文件

除了可以使用SAX或DOM解析XML文件之外,大家也可以使用Android内置的Pull解析器解析XML文件。 Pull解析器是一个开源的java项目,既可以用于android,也可以用于JavaEE。如果用在javaEE需要把其jar文件放入类路径中,因为Android已经集成进了Pull解析器,所以无需添加任何jar文件。android系统本身使用到的各种xml文件,其内部也是采用Pull解析器进行解析的。 Pull解析器的运行方式与SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。跟SAX不同的是, Pull解析器产生的事件是一个数字,而非方法,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值

使用Pull解析器生成XML文件

有些时候,我们需要生成一个XML文件,生成XML文件的方法有很多,如:可以只使用一个StringBuilder组拼XML内容,然后把内容写入到文件中;或者使用DOM API生成XML文件,或者也可以使用pull解析器生成XML文件,这里推荐大家使用Pull解析器。

使用Pull解析器生成一个与ljq.xml文件内容相同的myljq.xml文件,代码在本页下方备注


package com.xml.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.xml.domain.Person;

public class PullPersonService {
	public static void save(List<Person> persons, OutputStream outStream) throws Exception{
		XmlSerializer serializer = Xml.newSerializer();//定义一个接口来实现XML信息的串行化
		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;
	}
}


附件: 下载全部实例代码


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值