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

Android使用Pull解析和SAX解析两种方法解析XML格式数据

2019-03-05 18:59 1246 查看

在网络上传输数据时最常用的格式有两种:XML和JSON。解析XML格式数据常用的方法有两种:Pull解析和SAX解析。

首先假设服务器上有一个XML文件,文件内容为:

[code]<apps>
<app>
<id>1</id>
<name>Google Maps</name>
<version>1.0</version>
</app>

<app>
<id>2</id>
<name>Chrome</name>
<version>2.1</version>
</app>

<app>
<id>3</id>
<name>Google Play</name>
<version>2.3</version>
</app>
</apps>

假设已经使用OkHttp向服务器请求该文件,并将结果保存在responseData字符串里。

1.Pull解析

Pull解析是一个遍历文档的过程,具体代码如下:

[code]private void parseXMLWithPull(String responseData){//参数为存放数据的字符串
try{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();//获取XmlPullParserFactory实例
XmlPullParser xmlPullParser = factory.newPullParser();//获取XmlPullParser对象
xmlPullParser.setInput(new StringReader(responseData));//将获取到的数据传入XmlPullParser对象
int eventType = xmlPullParser.getEventType();//获取解析事件类型
String id = "";
String name = "";
String version = "";

while (eventType != XmlPullParser.END_DOCUMENT){//若解析未完成,继续解析
String nodeName = xmlPullParser.getName();//获取节点名字
switch (eventType){//根据解析事件类型判断是开始标签还是结束标签
case XmlPullParser.START_TAG:{//如果是开始标签通过判断将数据写入字符串
if ("id".equals(nodeName)){
id = xmlPullParser.nextText();//调用nextText()方法获取节点内具体的内容
}
else if ("name".equals(nodeName)){
name = xmlPullParser.nextText();
}
else if ("version".equals(nodeName)){
version = xmlPullParser.nextText();
}
break;
}
case XmlPullParser.END_TAG:{//如果是结束标签则表示某个节点完成解析
if ("app".equals(nodeName)){
Log.d("MainActivity","id is " + id);
Log.d("MainActivyty","name is " + name);
Log.d("MainActivity","version is " + version);

}
break;
}
default:

break;
}
eventType = xmlPullParser.next();//获取下一个解析事件类型
}
}catch (Exception e){
e.printStackTrace();
}
}

分析上述代码,可将解析过程分为如下几步:

(1)首先获取一个XmlPullParserFactory实例,并借助这个实例得到XmlPullParser对象。

(2)调用XmlPullParser对象的setInput()方法,把从服务器获取到的XML数据传入到对象中。

(3)从上到下开始遍历数据。通过XmlPullParser对象的getEventType()方法判断当前的解析事件类型是不是开始标签,通过调用XmlPullParser对象的getName()方法可以获取该标签节点的名字。

(4)如果是id/name/version节点的开始标签,就调用XmlPullParser对象的nextText()方法获取该节点里的内容,并且此时事件类型会自动跳转到该节点的结束标签,所以id/name/version节点的结束标签会被跳过,当getEventType()方法获取到的是结束标签时,该结束标签一定是app或apps的结束标签。

(5)倘若事件类型是app的结束标签就表示一个app节点的内容解析完成,通过Log将内容打印出来;

(6)在一个while循环中不断地进行解析,就可以将所有app节点的内容都解析出来。

 

2.SAX解析

SAX解析将数据的解析过程写在一个类里面,该类继承自DefaultHandler类,并且有5个方法需要重写,分别为:

(1)startDocument()方法:在开始XML解析的时候调用。

(2)startElement()方法:在开始解析某个节点的时候调用。

(3)characters()方法:在获取节点内容的时候调用。

(4)endElement()方法:在完成解析某个节点的时候调用。

(5)endDocument()方法:在完成整个XML解析的时候调用。

具体代码如下:

[code]public class ContentHandler extends DefaultHandler{
private String nodeName;

private  StringBuilder id;

private StringBuilder name;

private  StringBuilder version;

@Override
public void startDocument() throws SAXException{//进行初始化操作
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}

@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException{//开始解析节点的时候记录该节点的名字
nodeName = localName;
}

@Override
public void characters(char[] ch,int start, int length) throws  SAXException{
if ("id".equals(nodeName)){//将解析内容保存在字符串中
id.append(ch,start,length);
}
else if ("name".equals(nodeName)){
name.append(ch,start,length);
}
else if ("version".equals(nodeName)){
version.append(ch,start,length);
}
}

@Override
public void endElement(String uri,String localName,String qName) throws SAXException{//解析节点结束时打印该节点内容
if ("app".equals(localName)){
Log.d("ContentHandler","id is "+ id.toString().trim());//调用trim()方法清除内容里面的回车或换行符
Log.d("ContentHandler","name is " + name.toString().trim());
Log.d("ContentHandler","name is " + version.toString().trim());
id.setLength(0);//将字符串里的内容打印后清空字符串,方便解析下一个节点时使用
name.setLength(0);
version.setLength(0);
}
}

@Override
public void endDocument() throws SAXException{//结束解析
super.endDocument();
}
}

上述代码中新建了一个ContentHandler类继承DefaultHandler类,类里面重写了5个父类方法,其中:startDocument()方法完成初始化操作,startElement()方法记录开始解析的节点名字,characters()方法通过节点名字判断该节点是否是id/name/version节点,endElement()方法内打印出节点内容,endDocument()方法结束解析。

在创建完ContentHandler类之后就可以开始解析工作了,代码如下:

[code] private void parseXMLWithSAX(String responseData){
try{
SAXParserFactory factory = SAXParserFactory.newInstance();//获取一个SAXParserFactory实例
XMLReader xmlReader = factory.newSAXParser().getXMLReader();//通过SAXParserFactory实例获取XMLReader对象
ContentHandler handler = new ContentHandler();//创建ContentHandler实例
xmlReader.setContentHandler(handler);//将ContentHandler实例设置到XMLReader对象中
xmlReader.parse(new InputSource(new StringReader(responseData)));//将从服务器中获取的数据传到XMLReader的parse()方法内开始解析工作
}catch (Exception e){
e.printStackTrace();
}
}

分析上述代码,可将解析过程分为如下几步:

(1)获取一个SAXParserFactory实例。

(2)通过SAXParserFactory实例得到XMLReader对象。

(3)创建ContentHandler实例并将ContentHandler实例设置到XMLReader对象中。

(4)将从服务器中获取的数据传到XMLReader的parse()方法内开始解析工作。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: