在Android平臺(tái)上可以使用Simple?API?for XML(SAX) 、 Document Object Model(DOM)和Android附帶的pull解析器解析XML文件。
成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),柘城企業(yè)網(wǎng)站建設(shè),柘城品牌網(wǎng)站建設(shè),網(wǎng)站定制,柘城網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷(xiāo),網(wǎng)絡(luò)優(yōu)化,柘城網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿(mǎn)足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專(zhuān)業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶(hù)成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。下面是本例子要解析的XML文件:itcast.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>
例子定義了一個(gè)javabean用于存放上面解析出來(lái)的xml內(nèi)容, 這個(gè)javabean為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;
}
}
1. SAX解析XML文件
SAX是一個(gè)解析速度快并且占用內(nèi)存少的xml解析器,非常適合用于Android等移動(dòng)設(shè)備。?SAX解析XML文件采用的是事件驅(qū)動(dòng),也就是說(shuō),它并不需要解析完整個(gè)文檔,在按內(nèi)容順序解析文檔的過(guò)程中,SAX會(huì)判斷當(dāng)前讀到的字符是否合法XML語(yǔ)法中的某部分,如果符合就會(huì)觸發(fā)事件。所謂事件,其實(shí)就是一些回調(diào)(callback)方法,這些方法(事件)定義在ContentHandler接口。
public static List<Person> readXML(InputStream inStream) {
try {
//創(chuàng)建解析器
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
//設(shè)置解析器的相關(guān)特性,true表示開(kāi)啟命名空間特性
saxParser.setProperty("http://xml.org/sax/features/namespaces",true);
XMLContentHandler handler = new XMLContentHandler();
saxParser.parse(inStream, handler);
inStream.close();
return handler.getPersons();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//SAX類(lèi):DefaultHandler,它實(shí)現(xiàn)了ContentHandler接口。在實(shí)現(xiàn)的時(shí)候,只需要繼承該類(lèi),重載相應(yīng)的方法即可。
public class XMLContentHandler extends DefaultHandler {
private List<Person> persons = null;
private Person currentPerson;
private String tagName = null;//當(dāng)前解析的元素標(biāo)簽
public List<Person> getPersons() {
return persons;
}
//接收文檔開(kāi)始的通知。當(dāng)遇到文檔的開(kāi)頭的時(shí)候,調(diào)用這個(gè)方法,可以在其中做一些預(yù)處理的工作。
@Override
public void startDocument() throws SAXException {
persons = new ArrayList<Person>();
}
//接收元素開(kāi)始的通知。當(dāng)讀到一個(gè)開(kāi)始標(biāo)簽的時(shí)候,會(huì)觸發(fā)這個(gè)方法。其中namespaceURI表示元素的命名空間;
//localName表示元素的本地名稱(chēng)(不帶前綴);qName表示元素的限定名(帶前綴);atts 表示元素的屬性集合
@Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if(localName.equals("person")){
currentPerson = new Person();
currentPerson.setId(Integer.parseInt(atts.getValue("id")));
}
this.tagName = localName;
}
//接收字符數(shù)據(jù)的通知。該方法用來(lái)處理在XML文件中讀到的內(nèi)容,第一個(gè)參數(shù)用于存放文件的內(nèi)容,
//后面兩個(gè)參數(shù)是讀到的字符串在這個(gè)數(shù)組中的起始位置和長(zhǎng)度,使用new String(ch,start,length)就可以獲取內(nèi)容。
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if(tagName!=null){
String data = new String(ch, start, length);
if(tagName.equals("name")){
this.currentPerson.setName(data);
}else if(tagName.equals("age")){
this.currentPerson.setAge(Short.parseShort(data));
}
}
}
//接收文檔的結(jié)尾的通知。在遇到結(jié)束標(biāo)簽的時(shí)候,調(diào)用這個(gè)方法。其中,uri表示元素的命名空間;
//localName表示元素的本地名稱(chēng)(不帶前綴);name表示元素的限定名(帶前綴)
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if(localName.equals("person")){
persons.add(currentPerson);
currentPerson = null;
}
this.tagName = null;
}
}
2. DOM解析XML文件
DOM解析XML文件時(shí),會(huì)將XML文件的所有內(nèi)容讀取到內(nèi)存中,然后允許您使用DOM API遍歷XML樹(shù)、檢索所需的數(shù)據(jù)。使用DOM操作XML的代碼看起來(lái)比較直觀,并且,在某些方面比基于SAX的實(shí)現(xiàn)更加簡(jiǎn)單。但是,因?yàn)镈OM需要將XML文件的所有內(nèi)容讀取到內(nèi)存中,所以?xún)?nèi)存的消耗比較大,特別對(duì)于運(yùn)行Android的移動(dòng)設(shè)備來(lái)說(shuō),因?yàn)樵O(shè)備的資源比較寶貴,所以建議還是采用SAX來(lái)解析XML文件,當(dāng)然,如果XML文件的內(nèi)容比較小采用DOM是可行的。
public static List<Person> readXML(InputStream inStream) {
List<Person> persons = new ArrayList<Person>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(inStream);
Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName("person");//查找所有person節(jié)點(diǎn)
for (int i = 0; i < items.getLength(); i++) {
Person person = new Person();
//得到第一個(gè)person節(jié)點(diǎn)
Element personNode = (Element) items.item(i);
//獲取person節(jié)點(diǎn)的id屬性值
person.setId(new Integer(personNode.getAttribute("id")));
//獲取person節(jié)點(diǎn)下的所有子節(jié)點(diǎn)(標(biāo)簽之間的空白節(jié)點(diǎn)和name/age元素)
NodeList childsNodes = personNode.getChildNodes();
for (int j = 0; j < childsNodes.getLength(); j++) {
Node node = (Node) childsNodes.item(j); //判斷是否為元素類(lèi)型
if(node.getNodeType() == Node.ELEMENT_NODE){
Element childNode = (Element) node;
//判斷是否name元素
if ("name".equals(childNode.getNodeName())) {
//獲取name元素下Text節(jié)點(diǎn),然后從Text節(jié)點(diǎn)獲取數(shù)據(jù)
person.setName(childNode.getFirstChild().getNodeValue());
} else if (“age”.equals(childNode.getNodeName())) {
person.setAge(new Short(childNode.getFirstChild().getNodeValue()));
}
}
}
persons.add(person);
}
inStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return persons;
}
3.Pull解析器解析XML文件
Pull解析器的運(yùn)行方式與SAX解析器相似。它提供了類(lèi)似的事件,如:開(kāi)始元素和結(jié)束元素事件,使用parser.next()可以進(jìn)入下一個(gè)元素并觸發(fā)相應(yīng)事件。事件將作為數(shù)值代碼被發(fā)送,因此可以使用一個(gè)switch對(duì)感興趣的事件進(jìn)行處理。當(dāng)元素開(kāi)始解析時(shí),調(diào)用parser.nextText()方法可以獲取下一個(gè)Text類(lèi)型元素的值。
//讀取XML
public static List<Person> readXML(InputStream inStream) {
XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(inStream, "UTF-8");
int eventType = parser.getEventType();
Person currentPerson = null;
List<Person> persons = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT://文檔開(kāi)始事件,可以進(jìn)行數(shù)據(jù)初始化處理
persons = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG://開(kāi)始元素事件
String name = parser.getName();
if (name.equalsIgnoreCase("person")) {
currentPerson = new Person();
currentPerson.setId(new Integer(parser.getAttributeValue(null, "id")));
} else if (currentPerson != null) {
if (name.equalsIgnoreCase("name")) {
currentPerson.setName(parser.nextText());// 如果后面是Text元素,即返回它的值
} else if (name.equalsIgnoreCase("age")) {
currentPerson.setAge(new Short(parser.nextText()));
}
}
break;
case XmlPullParser.END_TAG://結(jié)束元素事件
if (parser.getName().equalsIgnoreCase("person") && currentPerson != null) {
persons.add(currentPerson);
currentPerson = null;
}
break;
}
eventType = parser.next();
}
inStream.close();
return persons;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//成XML文件
//使用Pull解析器生成一個(gè)與itcast.xml文件內(nèi)容相同的myitcast.xml文件。
public static String writeXML(List<Person> persons, Writer writer){
XmlSerializer serializer = Xml.newSerializer();
try {
serializer.setOutput(writer);
serializer.startDocument("UTF-8", true);
//第一個(gè)參數(shù)為命名空間,如果不使用命名空間,可以設(shè)置為null
serializer.startTag("", "persons");
for (Person person : persons){
serializer.startTag("", "person");
serializer.attribute("", "id", person.getId().toString());
serializer.startTag("", "name");
serializer.text(person.getName());
serializer.endTag("", "name");
serializer.startTag("", "age");
serializer.text(person.getAge().toString());
serializer.endTag("", "age");
serializer.endTag("", "person");
}
serializer.endTag("", "persons");
serializer.endDocument();
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//使用代碼如下(生成XML文件):
File xmlFile = new File("myitcast.xml");
FileOutputStream outStream = new FileOutputStream(xmlFile);
OutputStreamWriter outStreamWriter = new OutputStreamWriter(outStream, "UTF-8");
BufferedWriter writer = new BufferedWriter(outStreamWriter);
writeXML(persons, writer);
writer.flush();
writer.close();
//如果只想得到生成的xml內(nèi)容,可以使用StringWriter:
StringWriter writer = new StringWriter();
writeXML(persons, writer);
String content = writer.toString();
4.SAX和PULL使用
區(qū)別為:SAX解析器的工作方式是自動(dòng)將事件推入事件處理器進(jìn)行處理,因此你不能控制事件的處理主動(dòng)結(jié)束;而Pull解析器的工作方式為允許你的應(yīng)用程序代碼主動(dòng)從解析器中獲取事件,正因?yàn)槭侵鲃?dòng)獲取事件,因此可以在滿(mǎn)足了需要的條件后不再獲取事件,結(jié)束解析。
你隨便找個(gè)sax和pull的例子比較一下就可以發(fā)現(xiàn),pull是一個(gè)while循環(huán),隨時(shí)可以跳出,而sax不是,sax是只要解析了,就必須解析完成。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)頁(yè)標(biāo)題:三種解析xml的方式-創(chuàng)新互聯(lián)
URL鏈接:http://jinyejixie.com/article48/dcjeep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開(kāi)發(fā)、App開(kāi)發(fā)、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站營(yíng)銷(xiāo)、服務(wù)器托管、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容