与***个 SAX 示例类似,以上代码完全没有特定于 Android 的地方。DOM 解析器将所有 XML 文档读取到内存中,然后允许您使用 DOM API 遍历 XML 树、检索所需的数据。这是非常直观的代码,并且,在某些方面比基于 SAX 的实现更加简单。但是,DOM 通常更加占用内存,因为一切内容都会先读取到内存中。这对于运行 Android 的移动设备来说是一个问题,但是当 XML 文档始终保持很小的大小时是可行的。这可能意味着,Android 的开发人员会认为 SAX 解析在 Android 应用程序上更加常见,因此为它提供了额外的实用工具。Android 还提供了另一种类型的 XML 解析器,它就是 pull 解析器。
XML pull 解析器
如前所述,Android 并未提供对 Java StAX API 的支持。但是,Android 确实附带了一个 pull 解析器,其工作方式类似于 StAX。它允许您的应用程序代码从解析器中获取事件,这与 SAX 解析器自动将事件推入处理程序相反。清单 10 显示了提要解析接口的一个 pull 解析器实现。
清单 10. 基于 Pull 解析器的实现
java代码:
- public class XmlPullFeedParser extends BaseFeedParser {
- public XmlPullFeedParser(String feedUrl) {
- super(feedUrl);
- }
- public List< Message > parse() {
- List< Message > messages = null;
- XmlPullParser parser = Xml.newPullParser();
- try {
- // auto-detect the encoding from the stream
- parser.setInput(this.getInputStream(), null);
- int eventType = parser.getEventType();
- Message currentMessage = null;
- boolean done = false;
- while (eventType != XmlPullParser.END_DOCUMENT && !done){
- String name = null;
- switch (eventType){
- case XmlPullParser.START_DOCUMENT:
- messages = new ArrayList< Message >();
- break;
- case XmlPullParser.START_TAG:
- name = parser.getName();
- if (name.equalsIgnoreCase(ITEM)){
- currentMessage = new Message();
- } else if (currentMessage != null){
- if (name.equalsIgnoreCase(LINK)){
- currentMessage.setLink(parser.nextText());
- } else if (name.equalsIgnoreCase(DESCRIPTION)){
- currentMessage.setDescription(parser.nextText());
- } else if (name.equalsIgnoreCase(PUB_DATE)){
- currentMessage.setDate(parser.nextText());
- } else if (name.equalsIgnoreCase(TITLE)){
- currentMessage.setTitle(parser.nextText());
- }
- }
- break;