最近在學習Android的開發知識。今天在看傳智博客黎老師的視頻剛好看到了關於xml文件操作的知識,自己在之前的學習使用中基本都是使用DOM的方式操作XML的文件,今天知道了其他的方式總結記錄下來方便后面自己使用。
Android里面操作xml文件主要有三種方式:
SAX方式,DOM方式,PULL方式。據說因為DOM的方式比較耗內存,而手機最糾結的就是存儲空間小的問題,所以在Android里面不提倡使用DOM的方式。而SAX方式和PULL方式的思想比較的相似,原理似乎是同出一則的,實現的思想好像是讀取字符串的每一個單詞一樣,每讀取一段就判斷讀取的是什么內容然后執行相應的方法,直至文件的結尾。
xml文件內容:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="30">
<name>liming</name>
<age>30</age>
</person>
<person id="23">
<name>limei</name>
<age>20</age>
</person>
</persons>
下面是三種方式讀取xml文件內容的方式:
SAX實現xml文件內容的讀取:

package cn.edu.gxnu.Service;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import cn.edu.gxnu.Domian.Person;
public class SAXPersonService {
/**
* SAX方式獲取XML文件的內容
* @param inStream
* @return
* @throws Throwable
*/
public List<Person> getPersons(InputStream inStream) throws Throwable{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
PersonParser personparser = new PersonParser();
parser.parse(inStream, personparser);
inStream.close();
return personparser.getPersons();
}
/**
*
* @author wmh
*
*/
private final class PersonParser extends DefaultHandler {
private List<Person> persons = null;
private Person person = null;
private String tag = null;
public List<Person> getPersons() {
return persons;
}
/**
* 讀取XML至文件開始時方法
*/
@Override
public void startDocument() throws SAXException {
persons = new ArrayList<Person>();
}
/**
* 讀取XML的元素節點的方法
*/
@Override
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
if("person".equals(localName)){
person = new Person();
person.setId(new Integer(attributes.getValue(0)));
}
tag = localName;
}
/**
* 讀取XML的文本內容時的方法
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if(tag != null){
String data = new String(ch , start , length);
if("name".equals(tag)){
person.setName(data);
}else if("age".equals(tag)) {
person.setAge(new Short(data));
}
}
}
/**
* 讀取到元素節點結束時的方法
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if("person".equals(localName)){
persons.add(person);
person = null;
}
tag = null;
}
}
}
DOM實現xml文件內容的讀取:

package cn.edu.gxnu.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 cn.edu.gxnu.Domian.Person;
public class DOMPersonService {
/**
* 使用DOM獲取XML文件的內容
* @param inStream
* @return
* @throws Throwable
*/
public List<Person> getPersons(InputStream inStream) throws Throwable{
List<Person> persons = new ArrayList<Person>();
//DOM文件創建工廠
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//DOM創建對象
DocumentBuilder builder = factory.newDocumentBuilder();
//獲取XML的DOM
Document document = builder.parse(inStream);
//獲取XML文件的內容
Element root = document.getDocumentElement();
//獲取XML文件的節點
NodeList personNode = root.getElementsByTagName("person");
for(int i = 0 ; i < personNode.getLength() ; i++){
Person person = new Person();
Element personElemt = (Element)personNode.item(i);
person.setId(new Integer(personElemt.getAttribute("id")));
//獲取當前節點的字節點
NodeList personChildNode = personElemt.getChildNodes();
for(int y = 0 ; y < personChildNode.getLength() ; y++){
if(personChildNode.item(y).getNodeType() == Node.ELEMENT_NODE){
Element childElent = (Element)personChildNode.item(y);
if("name".equals(childElent.getNodeName())){
person.setName(childElent.getFirstChild().getNodeValue());
}else if("age".equals(childElent.getNodeName())){
person.setAge(new Short(childElent.getFirstChild().getNodeValue()));
}
}
}
persons.add(person);
}
return persons;
}
}
PULL實現xml文件內容的讀取:

package cn.edu.gxnu.Service;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import android.util.Xml;
import cn.edu.gxnu.Domian.Person;
public class PULLPersonService {
/**
* PULL方式獲取XML文件內容
* @param inStream
* @return
* @throws Throwable
*/
public List<Person> getPersons(InputStream inStream) throws Throwable{
List<Person> persons = null;
Person person = null;
XmlPullParser parser = Xml.newPullParser();
parser.setInput(inStream, "UTF-8");
int eventType = parser.getEventType();
while(eventType != XmlPullParser.END_DOCUMENT){//判斷文件是否是文件的結尾,END_DOCUMENT文件結尾常量
switch(eventType){
case XmlPullParser.START_DOCUMENT://文件開始,START_DOCUMENT文件開始開始常量
persons = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG://元素標簽開始,START_TAG標簽開始常量
String name = parser.getName();
if("person".equals(name)){
person = new Person();
person.setId(new Integer(parser.getAttributeValue(0)));
}
if(person != null){
if("name".equals(name)){
person.setName(parser.nextText());
}
if("age".equals(name)){
person.setAge(new Short(parser.nextText()));
}
}
break;
case XmlPullParser.END_TAG://元素標簽結束,END_TAG結束常量
if("person".equals(parser.getName())){
persons.add(person);
person = null;
}
break;
}
//獲取當前元素標簽的類型
eventType = parser.getEventType();
}
return persons;
}
}
而構造XML的方式頁比較好理解,PULL的方式提供了構造文件,節點開始和結束的方法,只需要調用特定的方法傳入特定的內容即可完成XML文件的構造

package cn.edu.gxnu.Service;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import android.util.Xml;
import cn.edu.gxnu.Domian.Person;
public class PULLPersonService {
/**
* OputStram方式生成XML文件
* @param persons
* @param outStream
* @throws Throwable
*/
public static void save(List<Person> persons , OutputStream outStream) throws Throwable{
XmlSerializer serializer = Xml.newSerializer();
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();
}
}
這樣,就可以構造一個XML文件了,每個節點都是一對一對的出現的。