提醒大家Android系统还提供了另一种XML解析方式可以使你更好的处理这种情况,就是Pull方式解析XML数据。
Pull解析器和SAX解析器虽有区别但也有相似性。他们的区别为:SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。这是他们主要的区别。
而他们的相似性在运行方式上,Pull解析器也提供了类似SAX的事件(开始文档START_DOCUMENT和结束文档END_DOCUMENT,开始元素START_TAG和结束元素END_TAG,遇到元素内容TEXT等),但需要调用next() 方法提取它们(主动提取事件)。
Android系统中和Pull方式相关的包为org.xmlpull.v1,在这个包中提供了Pull解析器的工厂类XmlPullParserFactory和Pull解析器XmlPullParser,XmlPullParserFactory实例调用newPullParser方法创建 XmlPullParser解析器实例,接着XmlPullParser实例就可以调用getEventType()和next()等方法依次主动提取事 件,并根据提取的事件类型进行相应的逻辑处理。
下面我们就用上面介绍的Pull方式来实现解析XML形式的USGS地震数据的Demo例子。
程序首先也是定义解析用到的变量,在定义的用于解析xml数据的方法中
public ArrayList<EarthquakeEntry> parse(InputStream inStream)
定义了一个局部变量
boolean isDone = false;
用于标志在有满足条件时停止读取XML文档,退出解析过程。
主体部分首先创建XmlPullParser。
我们来看看代码:
- //创建XmlPullParser,有两种方式
- //方式一:使用工厂类XmlPullParserFactory
- XmlPullParserFactory pullFactory = XmlPullParserFactory.newInstance();
- XmlPullParser xmlPullParser = pullFactory.newPullParser();
- //方式二:使用Android提供的实用工具类android.util.Xml
- XmlPullParser xmlPullParser = Xml.newPullParser();
创建XmlPullParser有两种方式,一种是使用我们介绍的org.xmlpull.v1包中的工厂类XmlPullParserFactory。除了这种方式外,还可以使用android sdk提供的实用工具包android.util中的类Xml的newPullParser()方法直接创建。
接着为pull解析器设置要解析的xml文档数据,并使用主动的方式获取解析器中的事件.
- xmlPullParser.setInput(inStream, "UTF-8");
- int eventType = xmlPullParser.getEventType();
我们***添加AndroidXMLDemoPull.java文件中的内容
- public class AndroidXMLDemoPull extends Activity {
- /** Called when the activity is first created. */
- //定义显示的List相关变量
- ListView list;
- ArrayAdapter<EarthquakeEntry> adapter;
- ArrayList<EarthquakeEntry> earthquakeEntryList;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //获取地震数据流
- InputStream earthquakeStream = readEarthquakeDataFromFile();
- //Pull方式进行xml解析
- PullEarthquakeHandler pullHandler = new PullEarthquakeHandler();
- earthquakeEntryList = pullHandler.parse(earthquakeStream);
- //用ListView进行显示
- list = (ListView)this.findViewById(R.id.list);
- adapter = new ArrayAdapter<EarthquakeEntry>(this, android.R.layout.simple_list_item_1, earthquakeEntryList);
- list.setAdapter(adapter);
- }
- private InputStream readEarthquakeDataFromFile()
- {
- //从本地获取地震数据
- InputStream inStream = null;
- try {
- inStream = this.getAssets().open("USGS_Earthquake_1M2_5.xml");
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return inStream;
- }
- private InputStream readEarthquakeDataFromInternet()
- {
- //从网络上获取实时地震数据
- URL infoUrl = null;
- InputStream inStream = null;
- try {
- infoUrl = new URL("http://earthquake.usgs.gov/earthquakes/catalogs/1day-M2.5.xml");
- URLConnection connection = infoUrl.openConnection();
- HttpURLConnection httpConnection = (HttpURLConnection)connection;
- int responseCode = httpConnection.getResponseCode();
- if(responseCode == HttpURLConnection.HTTP_OK)
- {
- inStream = httpConnection.getInputStream();
- }
- } catch (MalformedURLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return inStream;
- }
- }
只是把进行XML解析的部分换成了如下方式:
- //Pull方式进行xml解析
- PullEarthquakeHandler pullHandler = new PullEarthquakeHandler();
- earthquakeEntryList = pullHandler.parse(earthquakeStream);