使用到的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());
}
}