清单 10. 基于 Pull 解析器的实现
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; case XmlPullParser.END_TAG: name = parser.getName(); if (name.equalsIgnoreCase(ITEM) && currentMessage != null){ messages.add(currentMessage); } else if (name.equalsIgnoreCase(CHANNEL)){ done = true; } break; } eventType = parser.next(); } } catch (Exception e) { throw new RuntimeException(e); } return messages; } } |
pull 解析器的运行方式与 SAX 解析器相似。它提供了类似的事件(开始元素和结束元素),但您需要使用 (parser.next()
提取它们。事件将作为数值代码被发送,因此您可以使用一个简单 case-switch。注意,解析并未像 SAX 解析那样监听元素的结束,而是在开始处完成了大部分处理。在 清单 10 的代码中,当某个元素开始时,您可以调用 parser.nextText()
从 XML 文档中提取所有字符数据。还需注意,您设置了一个标记(布尔变量 done
)来确定何时到达感兴趣内容的结束部分。这允许您提早停止读取 XML 文档,因为您知道代码将不会关心文档的其余部分。这有时非常实用,特别是当您只需要访问一小部分 XML 文档时。通过尽快停止解析,您可以极大地减少解析时间。这种优化对于连接速度较慢的移动设备尤为重要。pull 解析器可以提供一些性能优势以及易用性。它还可以用于编写 XML。
目前为止,我一直专注于通过 Internet 解析 XML。但是,有时您的应用程序可能需要将 XML 发送到远程服务器。显然,您可以只使用一个 StringBuilder
来创建 XML 字符串。另一种备选方法来自 清单 11 中的 Pull 解析器。
清单 11. 使用 pull 解析器编写 XML
private String writeXml(List<Message> messages){ XmlSerializer serializer = Xml.newSerializer(); StringWriter writer = new StringWriter(); try { serializer.setOutput(writer); serializer.startDocument("UTF-8", true); serializer.startTag("", "messages"); serializer.attribute("", "number", String.valueOf(messages.size())); for (Message msg: messages){ serializer.startTag("", "message"); serializer.attribute("", "date", msg.getDate()); serializer.startTag("", "title"); serializer.text(msg.getTitle()); serializer.endTag("", "title"); serializer.startTag("", "url"); serializer.text(msg.getLink().toExternalForm()); serializer.endTag("", "url"); serializer.startTag("", "body"); serializer.text(msg.getDescription()); serializer.endTag("", "body"); serializer.endTag("", "message"); } serializer.endTag("", "messages"); serializer.endDocument(); return writer.toString(); } catch (Exception e) { throw new RuntimeException(e); } } |
XmlSerializer
类是 前一部分 所使用的 XmlPullParser
包的一部分。它没有提取事件,而是将它们推出到数据流或编写程序中。在本例中,它仅仅将事件推送到了一个 java.io.StringWriter
实例中。它提供了一个直观的 API,通过各种方法开始和结束文档、处理元素以及添加文本或属性。这是 StringBuilder
的一种出色的替换方案,因为它可以更加轻松地确保您的 XML 具有良好结构。
您希望为 Android 设备构建何种类型的应用程序?无论如何,如果它需要通过 Internet 使用数据,那么都可能需要使用 XML。在本文中,您看到 Android 提供了大量用于处理 XML 的工具。您可以选择其中之一作为自己的工具,或者您可以根据用例来进行选择。大多数时间,使用 SAX 是比较安全的,并且 Android 提供了一种传统的 SAX 使用方法,以及一个便捷的 SAX 包装器。如果您的文档比较小,那么 DOM 可能是一种比较简单的方法。如果您的文档比较大,但您只需要文档的一部分,则 XML Pull 解析器可能是更为有效的方法。最后,对于编写 XML,Pull 解析器包也提供了一种便捷的方法。因此,无论您的 XML 需求如何,Android 都能在一定程度上满足它们。
名字 | 大小 | 下载方法 |
---|---|---|
AndroidXml.zip | 70KB | HTTP |
学习
- 用 Eclipse 开发 Android 应用程序(Frank Ableson,developerWorks,2008 年 2 月):开发 Android 应用程序最简单的方法是使用 Eclipse。在本教程中了解这方面的所有信息。
- Geronimo 叛逆者:使用集成软件包:Codehaus 的 Woodstox(Michael Galpin,developerWorks,2007 年 7 月):有关 SAX、DOM 和 pull 解析的比较,请阅读本文。
- 使用 StAX 解析 XML,第 2 部分: 拉式解析和事件(Peter Nehrer,developerWorks,2006 年 12 月):深入了解 XML pull 解析。
- 理解 SAX(Nicholas Chase,developerWorks,2003 年 7 月):阅读本教程,成为 SAX 解析方面的专家。
- 理解 DOM(Nicholas Chase,developerWorks,2007 年 3 月):有关 DOM 解析的更多信息,请阅读本教程。
- Android SDK 文档:了解这款用于开发和调试应用程序代码以及设计应用程序的工具。
- Open Handset Alliance 是一个由 47 家技术和移动公司组成的组织,这些公司共同致力于加快移动领域的创新。
- IBM XML 认证:了解如何才能成为一名 IBM 认证的 XML 及相关技术的开发人员。
- XML 技术库:developerWorks XML 专区提供了大量技术文章和技巧、教程、标准以及 IBM 红皮书。
- developerWorks 技术活动 和 网络广播:随时关注技术的最新进展。
- developerWorks 播客:收听一些与软件开发人员有关的有趣访谈和讨论。
获得产品和技术
- Android SDK:下载它并访问 API 参考指南,从官方 Android 开发人员站点获取关于 Android 的最新消息。
- Android Open Source Project:获取 Android 开源代码。
- Eclipse IDE:获取最新版本并开始使用它。
- IBM 产品评估试用版软件:下载或 在 IBM SOA Sandbox 中进行在线试用 并获得来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
讨论
- 参与论坛讨论。
- XML 专区讨论论坛:参与任何面向 XML 的论坛。
- developerWorks 博客:阅读这些博客并参与 developerWorks 社区。
Michael Galpin 是 eBay 的一名架构师。他经常为 developerWorks 撰写文章,同时在 TheServerSide.com 和 Java Developer 期刊上发表文章,他还有自己的 博客。他从 1998 年开始做职业程序员,并拥有加州理工学院数学专业的学士学位。