使用 stax 解析 xml part2

上传人:子 文档编号:42825617 上传时间:2018-06-03 格式:DOC 页数:22 大小:25.47KB
返回 下载 相关 举报
使用 stax 解析 xml part2_第1页
第1页 / 共22页
使用 stax 解析 xml part2_第2页
第2页 / 共22页
使用 stax 解析 xml part2_第3页
第3页 / 共22页
使用 stax 解析 xml part2_第4页
第4页 / 共22页
使用 stax 解析 xml part2_第5页
第5页 / 共22页
点击查看更多>>
资源描述

《使用 stax 解析 xml part2》由会员分享,可在线阅读,更多相关《使用 stax 解析 xml part2(22页珍藏版)》请在金锄头文库上搜索。

1、使用使用 StAXStAX 解析解析 XMLXML part2part2使用 StAX 解析 XML,第 2 部分: 拉式解析和事件探讨 StAX 基于事件迭代器的 API文档选项 打印本页将此页作为电子邮件发送讨论级别: 中级Peter Nehrer (pnehrerecliptical.ca), 自由撰稿人, 独立咨询顾问2007 年 7 月 05 日Streaming API for XML (StAX) 的基于事件迭代器 API 无论在性能还是在可用性上都有其他 XML 处理方法所不及的独到之处。第 1 部分介绍了 StAX 并详细讨论了它的基于指针的 API。本文进一步讨论基于事件迭

2、代器 API 及其为 Java? 开发人员带来的好处。使用 StAX 解析 XML第 1 部分(请参阅 参考资料)提到,StAX 提供了两种风格的处理 XML 的 API。基于指针的 API 是解析 XML 的低层方法。使用这种方法,应用程序沿着 XML 标记流移动指针,在每一步中检查解析器的状态来了解解析内容的更多信息。这种方法效率很高,特别适用于资源受限的环境。但是,基于指针的 API 不是面向对象的,因而不适合 Java 应用程序,尤其是在代码的可扩展性和可维护性与性能同样重要的企业领域中就更是如此。比方说,多层 Web 服务使用一般组件处理消息信封,而把特定于消息的内容处理(如参数绑定

3、)委托给其他组件完成,这种情况下就能从面向对象的方法中获益。StAX 提供的另一种风格的 API 以事件对象为中心。和基于指针的 API 一样,这也是一种基于拉的 XML 解析方法:应用程序使用提供的方法从解析器中拉出每个事件,按照需要处理该事件,依此类推,直到流解析完成(或者应用程序决定停止解析) 。XMLEventReader 接口简介事件迭代器 API 的主要接口是 XMLEventReader。和 XMLStreamReader 相比它的方法要少很多。这是因为 XMLEventReader 用于迭代事件对象流(事实上 XMLEventReader 扩展了 java.util.Itera

4、tor) 。关于解析事件的所有信息都封装在事件对象而不是读取器中。要使用基于事件迭代器的 API,应用程序首先必须从 XMLInputFactory 获得 XMLEventReader 的实例。工厂本身可用标准 JAXP 方法获得,它依靠抽象工厂模式支持可插入的服务提供者。这就使得获取默认的 XMLInputFactory 实现的实例和调用 XMLInputFactory.getInstance() 一样简单,如清单 1 所示。清单 1. 使用默认的 XMLInputFactory 实现创建 XMLEventReader String uri = “http:/www.atomenabled.

5、org/atom.xml“;URL url = new URL(uri);InputStream input = url.openStream();XMLInputFactory factory = XMLInputFactory.newInstance();XMLEventReader reader = factory.createXMLEventReader(uri, input);.XMLInputFactory 支持各种可用于创建 XMLEventReader 的输入源。除了 Java I/O 包中的 InputStream 和 Reader 之外,还支持 JAXP Source(来自

6、 TrAX) ,后者有助于集成 StAX 和 JAXP 的转换 API(TrAX) 。最后,还可以从 XMLStreamReader 创建 XMLEventReader。这种用法可以很好地说明基于事件迭代器的 API 如何堆叠于基于指针的 API 之上。事实上,实现通常要使用其他输入源创建一个 XMLStreamReader,然后再用它创建 XMLEventReader。使用 XMLEventReader 创建 XMLEventReader 之后,应用程序可用它迭代表示底层 XML 流的 InfoSet 片段的事件。由于接口 XMLEventReader 扩展了 java.util.Itera

7、tor,可以使用标准迭代器方法如 hasNext() 和 next()。但是请注意,不支持 remove() 方法,如果调用该方法会抛出异常。XMLEventReader 还提供了一些方便的方法来简化 XML 处理:nextEvent() 本质上是一种等同于 Iterator 的 next() 方法的强类型方法,它返回一个 XMLEvent,它是所有事件对象的基本接口。 nextTag() 能够跳过所有无关紧要的空白直到下一个开始或结束标记。因此返回值将是 StartElement 或 EndElement 事件(参见后述) 。该方法在处理纯元素(即文档类型声明 DTD 中声明为 EMPTY

8、的元素)内容时尤其有用。 getElementText() 可以访问纯文本元素的文本内容(开始标签到结束标签之间) 。从 StartElement 作为下一个预期事件开始,该方法在遇到 EndElement 之前将所有字符连接起来并返回结果字符串。 peek() 可以得到迭代器将返回的下一个事件(如果有)但是不移动迭代器。 清单 2 示范了 XMLEventReader 方法如何用于迭代 Atom 提要。Atom 是用于 Web 发布的一种连锁格式。该例首先获得 XMLInputFactory 的默认实例然后用它创建 XMLEventReader 来解析给定 URL 的 Atom 提要。迭代事

9、件的过程中,peek() 方法判定下一个事件是否从 icon 元素开始,该元素包含提要的图标 URL。如果是,则用 getElementText() 方法获取元素的文本内容(即图标 URL) ,然后停止迭代。清单 2. 使用 peek() 和 getElementText() 提取 Atom 提要的图标 URLfinal QName ICON = new QName(“http:/www.w3.org/2005/Atom“, “icon“);URL url = new URL(uri);InputStream input = url.openStream();XMLInputFactory f

10、actory = XMLInputFactory.newInstance();XMLEventReader reader = factory.createXMLEventReader(uri, input);try while (reader.hasNext() XMLEvent event = reader.peek();if (event.isStartElement() StartElement start = event.asStartElement();if (ICON.equals(start.getName() System.out.println(reader.getEleme

11、ntText();break;reader.nextEvent(); finally reader.close();input.close();返回的事件对象是不变的,应用程序可以保存到解析过程之后。但是应用程序也可定义不同的事件保留(或重用)策略,请参阅第 3 部分。应用程序也可用 getProperty(String) 从底层实现中获得一个定制的或预先定义的属性值。完成之后,应用程序应该调用读取器的 close() 方法关闭它,以便释放处理所占用的资源。使用 XMLEventReader 迭代事件流非常简单。处理这些事件需要知道和熟悉 StAX XMLEvent 的层次结构,下面我们来讨论

12、它。回页首 事件以及如何在 XML 解析器中使用事件前面已经强调过,XMLEventReader 在解析过程的每一步之后通过事件对象和应用程序通信自己的状态。整个 API 中使用的事件对象的标准类型定义在 javax.xml.stream.events 包中。接口 XMLEvent 表示类型层次结构的根,所有类型的事件必须扩展该接口。表示各种指针层事件类型(在基于指针的 API 中)定义在接口 XMLStreamConstants 中。不过,在第 3 部分将看到也可使用定制的接口(只要扩展了 XMLEvent) 。回页首 导航 XMLEvent 层次结构从解析器中检索到事件之后,应用程序通常需

13、要将其向下转换成 XMLEvent 的子类型以便访问该特定类型的信息。有多种方法,除了蛮力的 instanceof 检查(即通过一系列的 if/then 语句检查返回的事件是否实现了指定接口)以外,XMLEvent 还提供了 getEventType() 方法返回 XMLStreamConstants 中定义的事件常量。可基于该信息对事件进行向下类型转换。比方说,如果事件的 getEventType() 返回 START_ELEMENT,它就可以安全地转换成 StartElement。确定事件具体类型的另一种方法是使用为此提供的布尔查询方法。比如,如果事件是一个 Attribute 则 isA

14、ttribute() 返回 true,如果是 StartElement 则 isStartElement() 返回 true,等等。此外还有几种方便的方法可用于向下类型转换。asStartElement()、asEndElement() 和 asCharacters() 分别将相应的事件转换成 StartElement、EndElement 和 Characters。清单 3 中首先使用 isStartElement() 和 asStartElement() 方法确定检索的事件是否是 StartElement,然后将其向下转换成 StartElement 类型,从而访问元素名。清单 3. 确定

15、事件类型并向下转换成对应的接口/ get an event from the reader.if (event.isStartElement() StartElement start = event.asStartElement();/ use methods provided by StartElement.除了和类型层次结构有关的方法外,XMLEventType 还提供了 getLocation()、getSchemaType() 和 writeAsEncodedUnicode(Writer) 方法。getLocation() 返回的 Location 对象提供了关于事件在底层输入源中的位

16、置(比如该事件结束的行列号)的可选信息。getSchemaType() 用于检索和给定事件有关的 XML Schema 信息(如果实现支持该功能) 。writeAsEncodedUnicode(Writer) 方法以标准的方式定义了将事件对象写入 java.io.Writer 的契约。这些方法对于定义定制的事件(将在下一期讨论)特别有用,因为可以让序列化器委托 XMLEvent 派生类的序列化而不需要应用程序使用定制的序列化器。回页首 处理 XML 文档解析表示完整 XML 文档的流时,XMLEventReader 返回的第一个事件是 StartDocument。该接口提供了获得文档本身信息的方法。比如,getSystemId() 方法可以返回文档的系统 ID(如果知道的话) 。getVersion() 返回该文档使用的 XML 版本。默认的版本是 1.0,除非在文档的 XML 声明中指定了其他值。getCharacterEncodingScheme() 返回文档的字符编码,不论在 XML 声明中显式指定还是解析器自动检测

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号