Using StAX

通常,StAX 程序员使用XMLInputFactoryXMLOutputFactoryXMLEventFactory类创建 XML 流读取器,写入器和事件。通过在工厂上设置属性来完成配置,从而可以使用工厂上的setProperty方法将特定于实现的设置传递给基础实现。同样,可以使用getProperty factory 方法查询特定于实现的设置。

下面介绍XMLInputFactoryXMLOutputFactoryXMLEventFactory类,然后讨论资源分配,名称空间和属性 管理,错误处理,最后使用游标和迭代器 API 读写流。

StAX 工厂类别

StAX 工厂类。 XMLInputFactoryXMLOutputFactoryXMLEventFactory,让您定义和配置 XML 流读取器,流写入器和事件类的实现实例。

XMLInputFactory

XMLInputFactory类可让您配置工厂创建的 XML 流读取器处理器的实现实例。通过调用类newInstance的方法来创建抽象类XMLInputFactory的新实例。然后,使用静态方法XMLInputFactory\.newInstance创建新的工厂实例。

派生自 JAXP 的XMLInputFactory\.newInstance方法通过使用以下查找过程来确定要加载的特定XMLInputFactory实现类:

在获得对适当的XMLInputFactory的引用之后,应用程序可以使用工厂来配置和创建流实例。下表列出了XMLInputFactory支持的属性。有关更详细的列表,请参见 StAX 规范。

Property Description
isValidating 打开特定于实现的验证。
isCoalescing (必需) 要求处理器合并相邻的字符数据。
isNamespaceAware 关闭名称空间支持。所有实现都必须支持名称空间。对非命名空间感知文档的支持是可选的。
isReplacingEntityReferences (必需) 要求处理器将内部实体引用替换为其替换值,并将其报告为描述实体的字符或事件集。
isSupportingExternalEntities (必填) 要求处理器解析外部解析的实体。
reporter (必填) 设置并获取XMLReporterinterface的实现。
resolver (必填) 设置并获取XMLResolverinterface的实现。
allocator (必填) 设置并获取XMLEventAllocatorinterface的实现。

XMLOutputFactory

通过调用类newInstance的方法来创建抽象类XMLOutputFactory的新实例。然后使用静态方法XMLOutputFactory\.newInstance来创建新的工厂实例。用于获取实例的算法与XMLInputFactory相同,但是引用了javax\.xml\.stream\.XMLOutputFactory系统属性。

XMLOutputFactory仅支持一个属性javax\.xml\.stream\.isRepairingNamespaces。此属性是必需的,其 Object 是创建默认前缀并将其与命名空间 URI 关联。有关更多信息,请参见 StAX 规范。

XMLEventFactory

通过调用类newInstance的方法来创建抽象类XMLEventFactory的新实例。然后使用静态方法XMLEventFactory\.newInstance来创建新的工厂实例。该工厂引用javax\.xml\.stream\.XMLEventFactory属性来实例化工厂。用于获取实例的算法与XMLInputFactoryXMLOutputFactory相同,但是引用了javax\.xml\.stream\.XMLEventFactory系统属性。

XMLEventFactory没有默认属性。

资源,命名空间和错误

StAX 规范处理资源解析,属性和名称空间,以及错误和异常,如下所述。

Resource Resolution

XMLResolverinterface提供了一种方法来设置在 XML 处理期间解析资源的方法。应用程序在XMLInputFactory上设置interface,然后在该工厂实例创建的所有处理器上设置interface。

属性和命名空间

StAX 处理器使用游标interface中的查找方法和字符串 以及迭代器interface中的AttributeNamespace事件来报告属性。请注意,尽管将名称空间与游标和迭代器 API 中的属性分开报告,但名称空间被视为属性。还要注意,名称空间处理对于 StAX 处理器是可选的。有关名称空间绑定和可选名称空间处理的完整信息,请参见 StAX 规范。

错误报告和异常处理

所有致命错误均通过javax\.xml\.stream\.XMLStreamExceptioninterface报告。所有非致命错误和警告均使用javax\.xml\.stream\.XMLReporterinterface报告。

读取 XML 流

如本类前面所述,使用 StAX 处理器读取 XML 流的方式(更重要的是,获得的回报)会因使用 StAX 光标 API 或事件迭代器 API 的不同而有很大差异。以下两节描述了如何使用这些 API 中的每一个读取 XML 流。

Using XMLStreamReader

StAX 光标 API 中的XMLStreamReaderinterface使您只能向前读取 XML 流或文档,一次仅读取信息集中的一项。以下方法可用于从流中提取数据或跳过不需要的事件:

XMLStreamReader的实例在任何时候都有一个当前事件,其方法将在该事件上运行。在流上创建XMLStreamReader的实例时,当前的初始事件是START_DOCUMENT状态。然后,可以使用XMLStreamReader\.next方法移至流中的下一个事件。

读取属性,属性和命名空间

XMLStreamReader\.next方法将在流中加载下一个事件的属性。然后,您可以通过调用XMLStreamReader\.getLocalNameXMLStreamReader\.getText方法来访问这些属性。

XMLStreamReader光标位于StartElement事件上时,它将读取事件的名称和任何属性,包括名称空间。可以使用索引值访问事件的所有属性,也可以通过名称空间 URI 和本地名称来查找事件的所有属性。但是请注意,只有在当前StartEvent上声明的名称空间可用。不会维护先前声明的名称空间,并且不会删除重新声明的名称空间。

XMLStreamReader Methods

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 规范,展示了如何实例化 Importing 工厂,创建读取器以及对 XML 流的元素进行迭代:

XMLInputFactory f = XMLInputFactory.newInstance();
XMLStreamReader r = f.createXMLStreamReader( ... );
while(r.hasNext()) {
    r.next();
}

Using XMLEventReader

StAX 事件迭代器 API 中的XMLEventReader API 提供了将 XML 流中的事件 Map 到可以自由重用的已分配事件对象的方法,并且该 API 本身可以扩展为处理自定义事件。

XMLEventReader提供了四种迭代解析 XML 流的方法:

例如,以下代码段说明了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);
}

Reading Attributes

您可以从与其关联的javax\.xml\.stream\.StartElement中访问属性,如下所示:

public interface StartElement extends XMLEvent {
    public Attribute getAttributeByName(QName name);
    public Iterator getAttributes();
}

您可以在StartElementinterface上使用getAttributes方法在该StartElement上声明的所有属性上使用Iterator

Reading Namespaces

与读取属性类似,使用通过在StartElementinterface上调用getNamespaces方法创建的Iterator读取名称空间。仅返回当前StartElement的名称空间,应用程序可以使用StartElement\.getNamespaceContext获取当前名称空间上下文。

编写 XML 流

StAX 是 Double 向 API,游标和事件迭代器 API 都有自己的一组interface,用于编写 XML 流。与用于读取流的interface一样,用于游标和事件迭代器的 writer API 之间存在显着差异。以下各节描述如何使用这些 API 中的每一个编写 XML 流。

Using XMLStreamWriter

StAX 光标 API 中的XMLStreamWriterinterface使应用程序可以写回 XML 流或创建全新的流。 XMLStreamWriter 具有允许您执行以下操作的方法:

请注意,不需要XMLStreamWriter实现对 Importing 执行格式正确或有效性检查。虽然某些实现可能会执行严格的错误检查,但其他实现则可能不会。您实现的规则将应用于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>

Using XMLEventWriter

StAX 事件迭代器 API 中的XMLEventWriterinterface使应用程序可以写回 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,直到在流中添加或遇到AttributeNamespace以外的事件。这意味着,当您向流中添加AttributeNamespace时,会将其附加到当前StartElement事件中。

您可以使用Characters方法转义&\<\>"之类的字符。

setPrefix\(\.\.\.\)方法可用于显式绑定要在输出期间使用的前缀,而getPrefix\(\.\.\.\)方法可用于获取当前前缀。请注意,默认情况下,XMLEventWriter将名称空间绑定添加到其内部名称空间 Map。对于绑定它们的事件,前缀在相应的EndElement之后超出范围。

首页