使用 StAX
原文: https://docs.oracle.com/javase/tutorial/jaxp/stax/using.html
通常,StAX 程序员使用XMLInputFactory
, XMLOutputFactory
和XMLEventFactory
类创建 XML 流读取器,编写器和事件。通过在工厂上设置属性来完成配置,从而可以使用工厂上的setProperty
方法将特定于实现的设置传递给底层实现。同样,可以使用getProperty
工厂方法查询特定于实现的设置。
下面介绍XMLInputFactory
, XMLOutputFactory
和XMLEventFactory
类,然后讨论资源分配,命名空间和属性管理,错误处理,最后阅读和使用游标和迭代器 API 编写流。
StAX 工厂类
StAX 工厂类。 XMLInputFactory
, XMLOutputFactory
和XMLEventFactory
,让您定义和配置 XML 流阅读器,流编写器和事件类的实现实例。
的 XMLInputFactory
XMLInputFactory
类允许您配置工厂创建的 XML 流读取器处理器的实现实例。抽象类XMLInputFactory
的新实例是通过调用类上的newInstance
方法创建的。然后使用静态方法XMLInputFactory.newInstance
创建新的工厂实例。
从[JGP]派生, XMLInputFactory.newInstance
方法通过使用以下查找过程确定要加载的特定XMLInputFactory
实现类:
使用
javax.xml.stream.XMLInputFactory
系统属性。使用 Java SE 平台的 Java 运行时环境(JRE)目录中的
lib / xml.stream.properties
文件。使用 Services API(如果可用)通过查看 JRE 可用的 JAR 文件中的
META-INF / services / javax.xml.stream.XMLInputFactory
文件来确定类名。使用平台默认
XMLInputFactory
实例。
在获得对适当的XMLInputFactory
的引用之后,应用程序可以使用工厂来配置和创建流实例。下表列出了XMLInputFactory
支持的属性。有关更详细的列表,请参阅 StAX 规范。
javax.xml.stream.XMLInputFactory
Properties
属性 | 描述 |
---|---|
isValidating |
打开特定于实现的验证。 |
是合并 |
(必需)要求处理器合并相邻的字符数据。 |
isNamespaceAware |
关闭名称空间支持。所有实现都必须支持名称空间。支持非命名空间感知文档是可选的。 |
isReplacingEntityReferences |
(必需)要求处理器用其替换值替换内部实体引用,并将它们报告为描述实体的字符或事件集。 |
isSupportingExternalEntities |
(必填)要求处理器解析外部解析的实体。 |
记者 |
(必需)设置并获取XMLReporter 接口的实现。 |
旋转变压器 |
(必需)设置并获取XMLResolver 接口的实现。 |
分配器 |
(必需)设置并获取XMLEventAllocator 接口的实现。 |
XMLOutputFactory
抽象类XMLOutputFactory
的新实例是通过调用类上的newInstance
方法创建的。然后使用静态方法XMLOutputFactory.newInstance
创建新的工厂实例。用于获取实例的算法与XMLInputFactory
相同,但引用javax.xml.stream.XMLOutputFactory
系统属性。
XMLOutputFactory
仅支持一个属性, javax.xml.stream.isRepairingNamespaces
。此属性是必需的,其目的是创建默认前缀并将它们与名称空间 URI 相关联。有关更多信息,请参阅 StAX 规范。
XMLEventFactory
抽象类XMLEventFactory
的新实例是通过调用类上的newInstance
方法创建的。然后使用静态方法XMLEventFactory.newInstance
创建新的工厂实例。该工厂引用javax.xml.stream.XMLEventFactory
属性来实例化工厂。用于获取实例的算法与XMLInputFactory
和XMLOutputFactory
相同,但引用javax.xml.stream.XMLEventFactory
系统属性。
XMLEventFactory
没有默认属性。
资源,命名空间和错误
StAX 规范处理资源解析,属性和命名空间以及错误和异常,如下所述。
资源分辨率
XMLResolver
接口提供了一种设置在 XML 处理期间解析资源的方法的方法。应用程序在XMLInputFactory
上设置接口,然后在该工厂实例创建的所有处理器上设置接口。
属性和命名空间
属性由 StAX 处理器使用游标接口中的查找方法和字符串以及迭代器接口中的属性
和命名空间
事件进行报告。请注意,命名空间被视为属性,尽管命名空间与游标和迭代器 API 中的属性分开报告。另请注意,对于 StAX 处理器,名称空间处理是可选的。有关命名空间绑定和可选命名空间处理的完整信息,请参阅 StAX 规范。
错误报告和异常处理
通过javax.xml.stream.XMLStreamException
接口报告所有致命错误。使用javax.xml.stream.XMLReporter
接口报告所有非致命错误和警告。
阅读 XML 流
如本课程前面所述,使用 StAX 处理器读取 XML 流的方式 - 更重要的是,您获得的内容 - 根据您使用的是 StAX 游标 API 还是事件迭代器 API 而有很大差异。以下两节介绍如何使用这些 API 读取 XML 流。
使用 XMLStreamReader
StAX 游标 API 中的XMLStreamReader
接口允许您仅向前读取 XML 流或文档,一次只能在信息集中读取一个项目。以下方法可用于从流中提取数据或跳过不需要的事件:
获取属性的值
阅读 XML 内容
确定元素是否包含内容或为空
获取对属性集合的索引访问权限
获取对命名空间集合的索引访问权限
获取当前事件的名称(如果适用)
获取当前事件的内容(如果适用)
XMLStreamReader
的实例在任何时候都有一个当前事件,其方法在其上运行。当您在流上创建XMLStreamReader
的实例时,初始当前事件是START_DOCUMENT
状态。然后可以使用XMLStreamReader.next
方法步进到流中的下一个事件。
读取属性,属性和命名空间
XMLStreamReader.next
方法加载流中下一个事件的属性。然后,您可以通过调用XMLStreamReader.getLocalName
和XMLStreamReader.getText
方法来访问这些属性。
当XMLStreamReader
游标位于StartElement
事件上时,它会读取事件的名称和任何属性,包括命名空间。可以使用索引值访问事件的所有属性,也可以通过名称空间 URI 和本地名称查找。但请注意,只有当前StartEvent
上声明的命名空间可用;不维护以前声明的名称空间,并且不会删除重新声明的名称空间。
XMLStreamReader 方法
XMLStreamReader
提供以下方法来检索有关命名空间和属性的信息:
int getAttributeCount();
String getAttributeNamespace(int index);
String getAttributeLocalName(int index);
String getAttributePrefix(int index);
String getAttributeType(int index);
String getAttributeValue(int index);
String getAttributeValue(String namespaceUri, String localName);
boolean isAttributeSpecified(int index);
也可以使用另外三种方法访问命名空间:
int getNamespaceCount();
String getNamespacePrefix(int index);
String getNamespaceURI(int index);
实例化 XMLStreamReader
此示例取自 StAX 规范,显示了如何实例化输入工厂,创建读取器以及迭代 XML 流的元素:
XMLInputFactory f = XMLInputFactory.newInstance();
XMLStreamReader r = f.createXMLStreamReader( ... );
while(r.hasNext()) {
r.next();
}
使用 XMLEventReader
StAX 事件迭代器 API 中的XMLEventReader
API 提供了将 XML 流中的事件映射到可以自由重用的已分配事件对象的方法,并且可以扩展 API 本身来处理自定义事件。
XMLEventReader
提供了四种迭代解析 XML 流的方法:
next
:返回流中的下一个事件nextEvent
:返回下一个键入的 XMLEventhasNext
:如果要在流中处理更多事件,则返回 truepeek
:返回事件但不迭代到下一个事件
例如,以下代码片段说明了XMLEventReader
方法声明:
package javax.xml.stream;
import java.util.Iterator;
public interface XMLEventReader extends Iterator {
public Object next();
public XMLEvent nextEvent() throws XMLStreamException;
public boolean hasNext();
public XMLEvent peek() throws XMLStreamException;
// ...
}
要读取流上的所有事件然后打印它们,您可以使用以下内容:
while(stream.hasNext()) {
XMLEvent event = stream.nextEvent();
System.out.print(event);
}
阅读属性
您可以从关联的javax.xml.stream.StartElement
访问属性,如下所示:
public interface StartElement extends XMLEvent {
public Attribute getAttributeByName(QName name);
public Iterator getAttributes();
}
您可以使用StartElement
接口上的getAttributes
方法,在StartElement
上声明的所有属性上使用Iterator
。
读取命名空间
与读取属性类似,使用通过调用StartElement
接口上的getNamespaces
方法创建的迭代器
来读取命名空间。仅返回当前StartElement
的命名空间,并且应用程序可以使用StartElement.getNamespaceContext
获取当前命名空间上下文。
编写 XML 流
StAX 是一个双向 API,游标和事件迭代器 API 都有自己的一组用于编写 XML 流的接口。与用于读取流的接口一样,游标和事件迭代器的编写器 API 之间存在显着差异。以下部分描述了如何使用这些 API 编写 XML 流。
使用 XMLStreamWriter
StAX 游标 API 中的XMLStreamWriter
接口允许应用程序写回 XML 流或创建全新的流。 XMLStreamWriter 有一些方法可以让你:
编写格式良好的 XML
冲洗或关闭输出
写限定名称
请注意, XMLStreamWriter
实现不需要对输入执行格式良好或有效性检查。虽然某些实现可能会执行严格的错误检查,但其您实现的规则适用于XMLOutputFactory
类中定义的属性。
writeCharacters
方法用于转义&等字符。
,<
,>
和“
。绑定前缀可以通过传递前缀的实际值,使用setPrefix
方法,或通过设置默认名称空间声明的属性来处理。
以下示例取自 StAX 规范,演示了如何实例化输出工厂,创建编写器以及编写 XML 输出:
XMLOutputFactory output = XMLOutputFactory.newInstance();
XMLStreamWriter writer = output.createXMLStreamWriter( ... );
writer.writeStartDocument();
writer.setPrefix("c","http://c");
writer.setDefaultNamespace("http://c");
writer.writeStartElement("http://c","a");
writer.writeAttribute("b","blah");
writer.writeNamespace("c","http://c");
writer.writeDefaultNamespace("http://c");
writer.setPrefix("d","http://c");
writer.writeEmptyElement("http://c","d");
writer.writeAttribute("http://c", "chris","fry");
writer.writeNamespace("d","http://c");
writer.writeCharacters("Jean Arp");
writer.writeEndElement();
writer.flush();
此代码生成以下 XML(新行是非规范的):
<?xml version=’1.0’ encoding=’utf-8’?>
<a b="blah" xmlns:c="http://c" xmlns="http://c">
<d:d d:chris="fry" xmlns:d="http://c"/>Jean Arp</a>
使用 XMLEventWriter
StAX 事件迭代器 API 中的XMLEventWriter
接口允许应用程序写回 XML 流或创建全新的流。此 API 可以扩展,但主要 API 如下:
public interface XMLEventWriter {
public void flush() throws XMLStreamException;
public void close() throws XMLStreamException;
public void add(XMLEvent e) throws XMLStreamException;
// ... other methods not shown.
}
XMLEventWriter
的实例由XMLOutputFactory
的实例创建。迭代地添加流事件,并且在将事件添加到事件编写器实例之后不能修改事件。
属性,转义字符,绑定前缀
需要 StAX 实现来缓冲最后一个StartElement
,直到在流中添加或遇到属性
或命名空间
以外的事件。这意味着当您将属性
或命名空间
添加到流时,它会附加到当前StartElement
事件。
您可以使用字符
方法转义&
,<
,>
和“
。
setPrefix(...)
方法可用于显式绑定输出期间使用的前缀, getPrefix(...)
方法可用于获取当前前缀。请注意,默认情况下, XMLEventWriter
会将命名空间绑定添加到其内部命名空间映射中。对于绑定它们的事件,前缀超出了相应的EndElement
之后的范围。