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()***");
}
}
文档对象模型(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;
}
}
附件: 下载全部实例代码