先来看一下需要解析的数据:
<?xml version="1.0" encoding="UTF-8"?>
<weatherinfo author= "csdnHejingzhou" date ="晚上">
<cityname>北京</cityname>
<citycode>101010100</citycode>
<citydesc>北京</citydesc>
<publishtime>2016年08月18日18:00</publishtime>
<lastupdate>2016-08-18 18:12:20</lastupdate>
<live>
<updatetime>17:05</updatetime>
<temperature>18℃</temperature>
<humidity>17%</humidity>
<winddirect>东南风1级</winddirect>
</live>
<data />
</weatherinfo>
SAX解析
大概分为以下几个步骤:
①创建一个bean类,里面封装这需要解析元素的set 和 get 方法。
②创建一个Handler类继承DefaultHandler,实现几个解析方法。
③Test类,创建SAXParserFactory对象和SAXParser对象,然后获取需要解析的数据即可。
第一步就不用说了就是一些以元素名为属性的set get方法进行封装就好。
重点就是第二步,我们需要创建一个集成DefaultHandler的类,里面主要需要重写几个方法:
void | startDocument()
Receive notification of the beginning of the document.
|
void | startElement(String uri, String localName, String qName,Attributes attributes)
Receive notification of the start of an element.
|
void | characters(char[] ch, int start, int length)
Receive notification of character data inside an element.
|
void | endElement(String uri, String localName, String qName)
Receive notification of the end of an element.
|
void | endDocument()
Receive notification of the end of the document.
|
第一个方法:就是在开始读取文档的时候就开始进行调用,这里面可以一般可以进行做一些初始化的操作。
第二个方法:就是读取元素头的时候进行调用,就比如可以判断元素头,如果是制定的元素的时候,就可以实例化一些类,这里就比如当读到
的元素头是上边xml文件第一个元素头(weatherinfo)的时候就可以进行实例化这个Weatherinfo这个类。
因为在元素头部一般还会存在这个属性,比如这个例子中的author 和 date 这两个属性,这些数据也是需要在这个方法中进行解析的,同样也是
通过qName这个参数进行判断属性:比如要解析这个例子中的author 和Date这两属性的时候,我们可以这样做:
if (attributes.getQName(0).equals("author")) {// 设置标签中的属性
weatherinfo.setAuthor(attributes.getValue(0));
}
if (attributes.getQName(1).equals("date")) {
weatherinfo.setDate(attributes.getValue(1));
}
第三个方法:就是解析了,这里面就是先将需要解析的结果通过String接收一下,然后就是重复判断当前的节点名称是否是数据中的某项节点名称,
是的话就进行处理。
第四个方法:就是解析完毕后的处理环境了,这里可以清空一下临时赋值的元素名称。
第五个方法:就是结束文档的时后进行调用,同样和第一个方法一样之后调用一次,这里可以进行一些解析完数据之后要做的事情。
我们首先看看这个继承这个DefaultHandler的这个类:
package com.hejingzhou.decodexml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class XmlHandler extends DefaultHandler {
private Weatherinfo weatherinfo;
private String nodeName;
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("开始进入文档进行解析");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("weatherinfo")) {
weatherinfo = new Weatherinfo();
if (attributes.getQName(0).equals("author")) {// 设置标签中的属性
weatherinfo.setAuthor(attributes.getValue(0));
}
if (attributes.getQName(1).equals("date")) {
weatherinfo.setDate(attributes.getValue(1));
}
}
nodeName = qName;//将读到的元素头保存下来
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String info = new String(ch, start, length);
if (nodeName.equals("cityname")) {
weatherinfo.setCityname(info);
}
if (nodeName.equals("citycode")) {
weatherinfo.setCitycode(info);
}
if (nodeName.equals("citydesc")) {
weatherinfo.setCitydesc(info);
}
if (nodeName.equals("publishtime")) {
weatherinfo.setPublishtime(info);
}
if (nodeName.equals("lastupdate")) {
weatherinfo.setLastupdate(info);
}
if (nodeName.equals("updatetime")) {
weatherinfo.setUpdatetime(info);
}
if (nodeName.equals("temperature")) {
weatherinfo.setTemperature(info);
}
if (nodeName.equals("humidity")) {
weatherinfo.setHumidity(info);
}
if (nodeName.equals("winddirect")) {
weatherinfo.setWinddirect(info);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// 如果里面的数据位重复的时候,设置数组的时候,从这里可以判断末尾节点,然后就可以通过判断节点尾部字符进行设置add方法这样的话就不会进行重复添加
nodeName = "";//读取到元素尾部的标签时将 标签名称清空
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("结束文档的读取");
super.endDocument();
}
public Weatherinfo getWeatherinfo() {
return weatherinfo;
}
public void setWeatherinfo(Weatherinfo weatherinfo) {
this.weatherinfo = weatherinfo;
}
}
再来看看这个Test类:
<span style="white-space:pre"> </span>/**
* 采用SAX
*
* @param data
*/
private static void type$1(File data) {
// TODO Auto-generated method stub
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = factory.newSAXParser();
XmlHandler xmlHandler = new XmlHandler();
saxParser.parse(new File("Data.xml"), xmlHandler);
Weatherinfo weatherinfo = xmlHandler.getWeatherinfo();
System.out.println(weatherinfo);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
还是比较简单的,这样就可以解析出来这个数据并且放在这个类中。
PULL方式进行解析数据
pull这种方式需要依靠第三方的架包类,可自行下载 kxml2-2.2.2.jar
Android开发中还是推荐这种方式。
这个方法的核心还是循环判断这个当前元素的状态,和SAX类似,分为这个读取文档状态,开始读取标签状态,还有一个主要的就是解析文本状态了,对应的也就有结束读取标签,结束读取文档。
直接放代码吧:
<span style="white-space:pre"> </span>/**
* XmlPull
*
* @param data
*/
private static void type$2(File data) {
// TODO Auto-generated method stub
XmlPullParserFactory factory;
try {
factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
// xmlPullParser.setInput(new FileReader("Data.xml"));
xmlPullParser.setInput(new FileInputStream("Data.xml"), "UTF-8");
Weatherinfo weatherinfo = null;
String tag = "";
int even = xmlPullParser.getEventType();
while (even != XmlPullParser.END_DOCUMENT) {
switch (even) {
case XmlPullParser.START_DOCUMENT:
System.out.println("进入文档开始解析");
break;
case XmlPullParser.START_TAG:
if (xmlPullParser.getName().equals("weatherinfo")) {
weatherinfo = new Weatherinfo();
// 在这里进行访问标签属性
weatherinfo.setAuthor(xmlPullParser.getAttributeValue(0));
weatherinfo.setDate(xmlPullParser.getAttributeValue(1));
}
tag = xmlPullParser.getName();
break;
case XmlPullParser.TEXT:
if (tag.equals("cityname")) {
weatherinfo.setCityname(xmlPullParser.getText());
}
if (tag.equals("citycode")) {
weatherinfo.setCitycode(xmlPullParser.getText());
}
if (tag.equals("citydesc")) {
weatherinfo.setCitydesc(xmlPullParser.getText());
}
if (tag.equals("publishtime")) {
weatherinfo.setPublishtime(xmlPullParser.getText());
}
if (tag.equals("lastupdate")) {
weatherinfo.setLastupdate(xmlPullParser.getText());
}
if (tag.equals("updatetime")) {
weatherinfo.setUpdatetime(xmlPullParser.getText());
}
if (tag.equals("temperature")) {
weatherinfo.setTemperature(xmlPullParser.getText());
}
if (tag.equals("humidity")) {
weatherinfo.setHumidity(xmlPullParser.getText());
}
if (tag.equals("winddirect")) {
weatherinfo.setWinddirect(xmlPullParser.getText());
}
break;
case XmlPullParser.END_TAG:
tag = "";
break;
default:
break;
}
try {
even = xmlPullParser.next();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(weatherinfo);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取数据
*
* @return
*/
private static File getData() {
File file = null;
// TODO Auto-generated method stub
try {
HttpURLConnection hConnection = (HttpURLConnection) new URL("http://localhost:8081/XmlService/data.xml")
.openConnection();
if (hConnection.getResponseCode() == 200) {
FileOutputStream fOutputStream = new FileOutputStream("Data.xml");
InputStream inputStream = hConnection.getInputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = inputStream.read(buffer)) != -1) {
fOutputStream.write(buffer, 0, len);
}
fOutputStream.close();
file = new File("Data.xml");
file.createNewFile();
} else {
System.out.println("访问服务器失败,错误代码: " + hConnection.getResponseCode());
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return file;
}
源代码: http://download.csdn.net/detail/csdnhejingzhou/9608501