关于Android解析XML

使用到的JUnit测试:

1、创建一个类继承AndroidTestCase

2、在manifest.xml中添加

 <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="wxj.parserxmltest" >
</instrumentation>
<application>
<uses-library android:name="android.test.runner"/>
</application>

3、实现要测试的代码


写xml:

使用XmlSerializer接口。

<persons>
<person id="0">
<name>Leaon:0</name>
<age>20</age>
</person>
<person id="1">
<name>Leaon:1</name>
<age>21</age>
</person>
<person id="2">
<name>Leaon:2</name>
<age>22</age>
</person>
<person id="3">
<name>Leaon:3</name>
<age>23</age>
</person>
<person id="4">
<name>Leaon:4</name>
<age>24</age>
</person>
</persons>


public static void writeXML() throws Exception{
		List<Person> personList = getData();
		XmlSerializer serializer = Xml.newSerializer();
		//1.设置文件输出流
		FileOutputStream fos = new FileOutputStream("mnt/sdcard/persons.xml");
		serializer.setOutput(fos, "UTF-8");
		
		//开始文档<?xml version="1.0" encoding="utf-8"?>
		serializer.startDocument("UTF-8", true);
		
		serializer.startTag(null, "persons");		//设置开始标签<persons>
		
		Person person;
		for(int i=0;i<personList.size();i++){
			person = personList.get(i);
			serializer.startTag(null, "person");	//设置开始标签<person>
			serializer.attribute(null, "id", String.valueOf(person.getId()));	//设置属性<perosn id="">
			
			serializer.startTag(null, "name");		//设置开始标签<name>
			serializer.text(person.getName());		//设置内容
			serializer.endTag(null, "name");		//设置结束标签<name>
			
			serializer.startTag(null, "age");
			serializer.text(String.valueOf(person.getAge()));
			serializer.endTag(null, "age");
			
			serializer.endTag(null, "person");		//设置结束标签<person>
		}
		
		serializer.endTag(null, "persons");		//设置结束标签</persons>
		
		serializer.endDocument();
		//关闭流
		fos.close();
	}

读xml:

1、Pull方式。

是事件驱动的一种方式,跟sax方式有点类似,但是pull方式要自己去触发事件,调用nextXxx();

/**
	 * 使用XMLPullParser来解析xml文件
	 * @throws Exception 
	 */
	public static void pullParserXML() throws Exception{
		List<Person> personList = null;
		Person person = null;
		
		//XmlPullParser parser =XmlPullParserFactory.newInstance().newPullParser();
		//获得一个XmlPullParser对象
		XmlPullParser parser = Xml.newPullParser();		
		//设置流对象
		FileInputStream fis = new FileInputStream("mnt/sdcard/persons.xml");
		parser.setInput(fis, "UTF-8");
		//获得事件对象信息
		int eventType = parser.getEventType();
		while(eventType != parser.END_DOCUMENT){		//如果不等于结束的document时,则继续循环
			switch (eventType) {
			case XmlPullParser.START_TAG:		//	开始标签<persons>/<perosn>/<name>/<age>等	
				if("persons".equals(parser.getName())){
					personList = new ArrayList<Person>();	//初始化Person集合
				}else if("person".equals(parser.getName())){	//初始化person
					person = new Person();
					int id = Integer.parseInt(parser.getAttributeValue(null, "id"));
					person.setId(id);
				}else if("name".equals(parser.getName())){
					person.setName(parser.nextText());
				}else if("age".equals(parser.getName())){
					person.setAge(Integer.parseInt(parser.nextText()));
				}
				break;
			case XmlPullParser.END_TAG:			//	结束标签</persons> </perosn> </name> </age>等	
				if("person".equals(parser.getName())){
					personList.add(person);
				}
				break;
			default:
				break;
			}
			eventType = parser.next();		//获得下一个标签
		}
		fis.close();
		
		for(Person p : personList){
			Log.i("Utils",p.toString());
		}
	}


2、SAX方式

SAX

是基于事件驱动的。当然

android

的事件机制是基于回调函数的,在用

SAX

解析

xml

文档时候,在读取到文档

开始和结束标签时候就会回调一个事件,在读取到其他节点与内容时候也会回调一个事件。

 

既然涉及到事件,

就有事件源,

事件处理器。

SAX

接口中,

事件源是

org.xml.sax

包中的

XMLReader

它通过

parser()

方法来解析

XML

文档,

并产生事件。

事件处理器是

org.xml.sax

包中

Cont

entHander

DTDHander

ErrorHandler

以及

Entit

yResolver

4

个接口

 

XMLReader

通过相应事件处理器注册方法

set

XXXX()

来完成的与

Cont

entHander

DTDHander

ErrorHandler

以及

Entit

yResolver

4

个接口的连接,详细介绍请见下表:

SAX是基于事件驱动的。当然android的事件机制是基于回调函数的,在用SAX解析xml文档时候,在读取到文档开始和结束标签时候就会回调一个事件,在读取到其他节点与内容时候也会回调一个事件。 
既然涉及到事件,就有事件源,事件处理器。在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并产生事件。事件处理器是org.xml.sax包中ContentHander、DTDHander、ErrorHandler,以及EntityResolver这4个接口。

但是我们无需都继承这

4

个接口,

SDK

为我们提供了

DefaultHandler

类来处理,

DefaultHandler

类的一些主要事件

回调方法如下

但是我们无需都继承这

4

个接口,

SDK

为我们提供了

DefaultHandler

类来处理,

DefaultHandler

类的一些主要事件

回调方法如下

但是我们无需都继承这4个接口,SDK为我们提供了DefaultHandler类来处理,DefaultHandler类的一些主要事件回调方法如下:


public static void SAXParserXml() throws Exception{
		List<Person> personList = null;
		
		//创建一个SAXParserFactory
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//根据SAXParserFactory.newSAXParser()方法返回一个SAXParser解析器
		SAXParser parser = factory.newSAXParser();
		//根据SAXParser解析器获取事件源对象XMLReader
		XMLReader xmlReader = parser.getXMLReader();
		//实例化一个DefaultHandler对象
		MyDefaultHandler handler = new MyDefaultHandler();
		//连接事件源对象XMLReader到事件处理类DefaultHandler中
		xmlReader.setContentHandler(handler);
		//调用XMLReader的parse方法从输入源中获取到的xml数据
		FileInputStream fis = new FileInputStream("mnt/sdcard/persons.xml");
		xmlReader.parse(new InputSource(fis));
		//通过DefaultHandler返回我们需要的数据集合
		personList = handler.getPersonList();
		
		fis.close();		
		for(Person p : personList){
			Log.i("Utils",p.toString());
		}
	}
	
	static class MyDefaultHandler extends DefaultHandler{

		List<Person> personList;
		Person person;
		private String tagName;
		@Override
		public void startDocument() throws SAXException {
			System.out.println("----startDocument----");
		}


		@Override
		public void endDocument() throws SAXException {
			System.out.println("----endDocument----");
		}

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			tagName = localName.length()!=0 ? localName:qName;
			if(tagName.equals("persons")){
				personList = new ArrayList<Person>();
			}else if(tagName.equals("person")){
				person = new Person();
				person.setId(Integer.parseInt(attributes.getValue("id")));
			}
		}

		@Override
		public void endElement(String uri, String localName, String qName)
				throws SAXException {
			if(localName.equals("person")){
				personList.add(person);
			}
		}

		@Override
		public void characters(char[] ch, int start, int length)
				throws SAXException {
			if(tagName!=null){
				String content = new String(ch, start, length);
				if("name".equals(tagName)){
					person.setName(content);
				}else if("age".equals(tagName)){
					person.setAge(Integer.parseInt(content));
				}
			}
		}
		
		public List<Person> getPersonList() {
			return personList;
		}
	}


 

 

android

解析

xml

文件的方式

(

其二

 

 

android

解析

xml

文件的方式

(

其二

3、DOM方式

DOM方式解析xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据的,但是这样一来,如果xml文件很大呢?手机CPU处理能力当然不能与PC机器比,因此在处理效率方面就相对差了,当然这是对于其他方式处理xml文档而言。

/**
	 * 使用dom方式解析xml是先把整个xml文件读到内存中,然后根据DOM API来访问树形结构。如果文件一旦很大,那么久不太适合使用DOM方式了
	 * @throws Exception 
	 */
	public static void domParserXml() throws Exception{
		List<Person> personList =  new ArrayList<Person>();
		Person person = null;
		//创建一个DocumentBuilderFactory实例对象
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		//利用DocumentBuilderFactory来创建DocumentBuilder
		DocumentBuilder builder = factory.newDocumentBuilder();
		//加载xml文档
		FileInputStream fis = new FileInputStream("mnt/sdcard/persons.xml");
		Document document = builder.parse(fis);
		//获取文档的根结点(Element)
		Element root = document.getDocumentElement();
		//获取根结点中所有子节点的列表(NodeList)
		NodeList nodes = root.getElementsByTagName("person");
		Element personElement = null;
		Element nameElement = null;
		Element ageElement = null;
		for(int i=0;i<nodes.getLength();i++){
			person = new Person();
			personElement = (Element) nodes.item(i);			//<person>节点
			person.setId(Integer.parseInt(personElement.getAttribute("id")));		//id属性
			nameElement = (Element) personElement.getElementsByTagName("name").item(0);		//获得<name>
			person.setName(nameElement.getFirstChild().getNodeValue());
			ageElement = (Element) personElement.getElementsByTagName("age").item(0);		//获得<age>
			person.setAge(Integer.parseInt(ageElement.getFirstChild().getNodeValue()));
			personList.add(person);
		}
		fis.close();		
		for(Person p : personList){
			Log.i("Utils",p.toString());
		}
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值