Using StAX
通常,StAX 程序员使用XMLInputFactory
,XMLOutputFactory
和XMLEventFactory
类创建 XML 流读取器,写入器和事件。通过在工厂上设置属性来完成配置,从而可以使用工厂上的setProperty
方法将特定于实现的设置传递给基础实现。同样,可以使用getProperty
factory 方法查询特定于实现的设置。
下面介绍XMLInputFactory
,XMLOutputFactory
和XMLEventFactory
类,然后讨论资源分配,名称空间和属性 管理,错误处理,最后使用游标和迭代器 API 读写流。
StAX 工厂类别
StAX 工厂类。 XMLInputFactory
,XMLOutputFactory
和XMLEventFactory
,让您定义和配置 XML 流读取器,流写入器和事件类的实现实例。
XMLInputFactory
XMLInputFactory
类可让您配置工厂创建的 XML 流读取器处理器的实现实例。通过调用类newInstance
的方法来创建抽象类XMLInputFactory
的新实例。然后,使用静态方法XMLInputFactory\.newInstance
创建新的工厂实例。
派生自 JAXP 的XMLInputFactory\.newInstance
方法通过使用以下查找过程来确定要加载的特定XMLInputFactory
实现类:
-
使用
javax\.xml\.stream\.XMLInputFactory
系统属性。 -
使用 Java SE 平台的 Java Runtime Environment(JRE)目录中的
lib/xml\.stream\.properties
文件。 -
使用服务 API(如果可用),通过在 JRE 可用的 JAR 文件中的
META\-INF/services/javax\.xml\.stream\.XMLInputFactory
文件中查找来确定类名。 -
使用平台默认的
XMLInputFactory
实例。
在获得对适当的XMLInputFactory
的引用之后,应用程序可以使用工厂来配置和创建流实例。下表列出了XMLInputFactory
支持的属性。有关更详细的列表,请参见 StAX 规范。
javax\.xml\.stream\.XMLInputFactory
属性*
Property | Description |
---|---|
isValidating |
打开特定于实现的验证。 |
isCoalescing |
(必需) 要求处理器合并相邻的字符数据。 |
isNamespaceAware |
关闭名称空间支持。所有实现都必须支持名称空间。对非命名空间感知文档的支持是可选的。 |
isReplacingEntityReferences |
(必需) 要求处理器将内部实体引用替换为其替换值,并将其报告为描述实体的字符或事件集。 |
isSupportingExternalEntities |
(必填) 要求处理器解析外部解析的实体。 |
reporter |
(必填) 设置并获取XMLReporter interface的实现。 |
resolver |
(必填) 设置并获取XMLResolver interface的实现。 |
allocator |
(必填) 设置并获取XMLEventAllocator interface的实现。 |
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
属性来实例化工厂。用于获取实例的算法与XMLInputFactory
和XMLOutputFactory
相同,但是引用了javax\.xml\.stream\.XMLEventFactory
系统属性。
XMLEventFactory
没有默认属性。
资源,命名空间和错误
StAX 规范处理资源解析,属性和名称空间,以及错误和异常,如下所述。
Resource Resolution
XMLResolver
interface提供了一种方法来设置在 XML 处理期间解析资源的方法。应用程序在XMLInputFactory
上设置interface,然后在该工厂实例创建的所有处理器上设置interface。
属性和命名空间
StAX 处理器使用游标interface中的查找方法和字符串 以及迭代器interface中的Attribute
和Namespace
事件来报告属性。请注意,尽管将名称空间与游标和迭代器 API 中的属性分开报告,但名称空间被视为属性。还要注意,名称空间处理对于 StAX 处理器是可选的。有关名称空间绑定和可选名称空间处理的完整信息,请参见 StAX 规范。
错误报告和异常处理
所有致命错误均通过javax\.xml\.stream\.XMLStreamException
interface报告。所有非致命错误和警告均使用javax\.xml\.stream\.XMLReporter
interface报告。
读取 XML 流
如本类前面所述,使用 StAX 处理器读取 XML 流的方式(更重要的是,获得的回报)会因使用 StAX 光标 API 或事件迭代器 API 的不同而有很大差异。以下两节描述了如何使用这些 API 中的每一个读取 XML 流。
Using XMLStreamReader
StAX 光标 API 中的XMLStreamReader
interface使您只能向前读取 XML 流或文档,一次仅读取信息集中的一项。以下方法可用于从流中提取数据或跳过不需要的事件:
-
获取属性的值
-
读取 XML 内容
-
确定元素是否具有内容或为空
-
获取对属性集合的索引访问
-
获取对命名空间集合的索引访问
-
获取当前事件的名称(如果适用)
-
获取当前事件的内容(如果适用)
XMLStreamReader
的实例在任何时候都有一个当前事件,其方法将在该事件上运行。在流上创建XMLStreamReader
的实例时,当前的初始事件是START_DOCUMENT
状态。然后,可以使用XMLStreamReader\.next
方法移至流中的下一个事件。
读取属性,属性和命名空间
XMLStreamReader\.next
方法将在流中加载下一个事件的属性。然后,您可以通过调用XMLStreamReader\.getLocalName
和XMLStreamReader\.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 流的方法:
-
next
:返回流中的下一个事件 -
nextEvent
:返回下一个键入的 XMLEvent -
hasNext
:如果流中还有更多事件要处理,则返回 true -
peek
:返回事件,但不迭代到下一个事件
例如,以下代码段说明了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();
}
您可以在StartElement
interface上使用getAttributes
方法在该StartElement
上声明的所有属性上使用Iterator
。
Reading Namespaces
与读取属性类似,使用通过在StartElement
interface上调用getNamespaces
方法创建的Iterator
读取名称空间。仅返回当前StartElement
的名称空间,应用程序可以使用StartElement\.getNamespaceContext
获取当前名称空间上下文。
编写 XML 流
StAX 是 Double 向 API,游标和事件迭代器 API 都有自己的一组interface,用于编写 XML 流。与用于读取流的interface一样,用于游标和事件迭代器的 writer API 之间存在显着差异。以下各节描述如何使用这些 API 中的每一个编写 XML 流。
Using XMLStreamWriter
StAX 光标 API 中的XMLStreamWriter
interface使应用程序可以写回 XML 流或创建全新的流。 XMLStreamWriter 具有允许您执行以下操作的方法:
-
编写格式正确的 XML
-
冲洗或关闭输出
-
写出合格的名字
请注意,不需要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 中的XMLEventWriter
interface使应用程序可以写回 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
,直到在流中添加或遇到Attribute
或Namespace
以外的事件。这意味着,当您向流中添加Attribute
或Namespace
时,会将其附加到当前StartElement
事件中。
您可以使用Characters
方法转义&
,\<
,\>
和"
之类的字符。
setPrefix\(\.\.\.\)
方法可用于显式绑定要在输出期间使用的前缀,而getPrefix\(\.\.\.\)
方法可用于获取当前前缀。请注意,默认情况下,XMLEventWriter
将名称空间绑定添加到其内部名称空间 Map。对于绑定它们的事件,前缀在相应的EndElement
之后超出范围。