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

Android开发进阶(一)XML文件解析之SAX模式解析

2011-11-10 10:38 423 查看
 
SAX解析XML:

SAX基本原理:

采用事件驱动解析XML文件,以流式方式逐行的去读,它不需要解析完整个文档,在按内容顺序解析文档的过各中,SAX会判断当前讲到的字符是否合法XML语法中的某部分,如果符合就触发事件(例如startDocument()、endDocument()诸如此类的事件),它的特点是不会记录前面所碰到的标签,并且它是一个解析速度快并且占用内存少的XML解析器,

SAX解析步骤:

1、从SAXPraserFactory中创建一个新的实例

2、再从SAXParserFactory里得到一个新的SAX解析器对象SAXParser

3、再调用SAXParser对象的.parse()方法里面带两个参数一个是输入流一个是DefaultHandler对象这样就可以了。而DefaultHandler是实现了ContentHandler接口的。ContentHandler接口中定义了一系列的方法事件:诸如:

public abstract void startDocument ()


方法作用:文档解析触发此事件

public abstract void endDocument ()


方法作用:文档解析结束时触发此事件

public abstract void startElement (String uri, String localName, String qName, Attributes atts)


方法作用:当开始读取元素时触发此事件

参数说明:

uri:命名空间

localName:不带命名空间的前缀的标签名

qName:不定期命名空间前缀的标签名

atts:得到所有的属性各和相应的值

public abstract void endElement (String uri, String localName, String qName)


方法作用:读取的标签结束时触发此事件,参数说明同上

public abstract void characters (char[] ch, int start, int length)


方法作用:用来处理在XML文件中读到的内容

参数说明:

ch:用于存放文件的内容

start:所读到的字符串在这个数组中的起始位置

length:长度

我们可以用new String(ch,start,length)来获取内容

 

下面以person.xml文件为例采用SAX解析器来模拟解析这个XML文档:

<?xml version="1.0" encoding="UTF-8"?>

<persons>

<person id="23">

<name>李明</name>

<age>30</age>

</person>

<person id="20">

<name>李向梅</name>

<age>25</age>

</person>

</persons>


 

解析person.xml触发的事件为:

读到的标签及内容
触发事件
{文档开始}

startDocument()

<persons>

startElement(, "persons", null, "{Attributes}")

"\n\t"

characters("<persons>...</persons>", "12", "2")

<person>

startElement(, "person", null, "{Attributes}")

"\n\t\t"

characters("<persons>...</persons>", "31", "3")

<name>

startElement(, "name", null, "{Attributes}")

"李明"

characters("<persons>...</persons>", "40", "2")

</name>

endElement("", "name", null)

"\n\t\t"

characters("<persons>...</persons>", "50", "3")

<age>

startElement(, "age", null, "{Attributes}")

"30"

characters("<persons>...</persons>", "58", "2")

</age>

endElement("", "age", null)

"\n\t"

characters("<persons>...</persons>", "67", "2")

</person>

endElement("", "person", null)

"\n\t"

characters("<persons>...</persons>", "79", "2")

又重复<person>

….

{文档结束}

endDocument()

 

实例1:读取XML文件里的内容把这些内容构造成一个Person对象,然后读取这个XML文档里内容将其Person对象添加到一个List集合里:

Person类:

public class Person {

private Integer id;

private String name;

private short age;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public short getAge() {

return age;

}

public void setAge(short age) {

this.age = age;

}

@Override

public String toString() {

return "Person [age=" + age + ", id=" + id + ", name=" + name + "]";

}

}


 

业务bean:

public class SAXPersonService {

public static List<Person> readXml(InputStream inputStream)

throws Exception {

// 得到一个SAXParserFactory对象

SAXParserFactory spf = SAXParserFactory.newInstance();

// SAX解析对象

SAXParser saxParser = spf.newSAXParser();

// ContentHandler对象

XMLContentHandler handler = new XMLContentHandler();

// 开始解析

saxParser.parse(inputStream, handler);

// 关闭流

inputStream.close();

return handler.getPersons();

}

}


 

XMLContentHandler继承自DefalutHander而DefaultHandler实现ContentHandler接口

/**

* 继承于DefaultHandler  这个类也是实现ContentHandler

* @author Administrator

*

*/

public class XMLContentHandler extends DefaultHandler {

private List<Person> persons;

private Person person;

private String preTag;//当前标记

public List<Person> getPersons() {

return persons;

}

/**

* 文档开始

*/

public void startDocument() throws SAXException {

persons = new ArrayList<Person>();

}

/**

* 读取的文档内容

*/

public void characters(char[] ch, int start, int length)

throws SAXException {

if (person != null) {

String data = new String(ch, start, length);

// 判断前面的元素是否是"name"

if ("name".equals(preTag)) {

person.setName(data);

} else if ("age".equals(preTag)) {

person.setAge(new Short(data));

}

}

}

/**

* 元素开始

*/

public void startElement(String uri, String localName, String qName,

Attributes attributes) throws SAXException {

// 判断目前解析到的元素是否等于"person"

if ("person".equals(localName)) {

person = new Person();

// person.setId(Integer.parseInt(attributes.getValue(0)));

person.setId(Integer.parseInt(attributes.getValue("", "id")));

}

// 当前元素

preTag = localName;

}

/**

* 解析完一个元素后就把这个元素加到List里

*/

public void endElement(String uri, String localName, String qName)

throws SAXException {

if ("person".equals(localName) && person != null) {

persons.add(person);

person = null;

}

//再将这个当前元素设为null

preTag=null;

}

}


 

测试:

public class SAXPersonServiceTest extends AndroidTestCase {

private static final String TAG = "LogTest";

public void testSAXReadXml() throws Exception {

//从资源文件中获取输入流

InputStream inputStream = SAXPersonServiceTest.class.getClassLoader()

.getResourceAsStream("itcast.xml");

List<Person> list = SAXPersonService.readXml(inputStream);

for (Person person : list) {

System.out.println(person);

}

}

}

如需转载引用请注明出处:http://blog.csdn.net/jiahui524
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息