首先StAX的普及知识可以参考一下IBM Developement的下面这个系列文章
http://www.ibm.com/developerworks/cn/xml/x-stax1.html
http://www.ibm.com/developerworks/cn/xml/x-stax2.html
http://www.ibm.com/developerworks/cn/xml/x-stax3.html
同时参考了如下文章, 并作了简化
http://www.ibm.com/developerworks/cn/xml/x-1001mace/
先简单的讲一下我个人的基本思路
1. 采用流方式读取指定的节点
2. 转换成Node节点方式
3. 采用XPath, JAXB, 简单的Node处理等方式处理
我们采用maven的POM.xml作为例子,我们要解析
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>1.2</version>
<scope>runtime</scope>
</dependency>
1. 自定义Dependency事件
public class DependencyEvent implements XMLEvent {
public static final int DEPENDENCY_EVENT = 10000; // 定义事件枚举值, 0~255被StAX占用不要使用
......(省略其他属性定义)
private Node node;// 事件生成的Node节点
private List<XMLEvent> eventList;// 自定义的时间列表集合
// 构建函数
public DependencyEvent(List<XMLEvent> eventList) {
this.eventList = eventList;
}
// 生成自定义事件的Node节点
public Node getNode() throws XMLStreamException {
if (node == null) {
DOMResult result = new DOMResult(DOMUtils.getInstance()
.getBuilder().newDocument().createDocumentFragment());
XMLEventWriter writer = StAXUtils.getInstance().getOutputFactory()
.createXMLEventWriter(result);
for (XMLEvent event : eventList) {
writer.add(event);
}
writer.close();
node = result.getNode().getFirstChild();
}
return node;
}
...... (省略其他方法)
}
2. 自定义事件的Reader, 由于我们自定义了事件,默认的StAX的Reader无法识别
// 这里选择继承EventReaderDelegate类来简化, 当然也可以选择实现EventReader接口
// 其中最关键的就是peek()方法, 在peek方法中,可以根据自己的需求封装自定义事件
public class DependencyEventReader extends EventReaderDelegate {
private XMLEvent nextEvent;
public DependencyEventReader(InputStream in) throws XMLStreamException {
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader streamReader = factory.createXMLStreamReader(in);
XMLEventReader eventReader = factory.createXMLEventReader(streamReader);
super.setParent(eventReader);
}
@Override
public Object next() {
try {
return nextEvent();
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
}
@Override
public XMLEvent nextEvent() throws XMLStreamException {
if (nextEvent == null) {
nextEvent = peek();
}
XMLEvent result = nextEvent;
nextEvent = null;
return result;
}
@Override
public XMLEvent peek() throws XMLStreamException {
if (nextEvent == null && getParent().hasNext()) {
nextEvent = getParent().nextEvent();
if (nextEvent.isStartElement()) {
List<XMLEvent> eventList = new ArrayList<XMLEvent>();
QName qName = nextEvent.asStartElement().getName();
eventList.add(nextEvent);
if (qName.getLocalPart().equals("dependency")) {
int level = 1;
while (getParent().hasNext()) {
XMLEvent event = getParent().nextEvent();
eventList.add(event);
if (event.isStartElement()) {
level++;
} else if (event.isEndElement()) {
level--;
if (level == 0) {
break;
}
}
}
// 这个是关键, 生成自定义事件
nextEvent = new DependencyEvent(eventList);
}
}
}
return nextEvent;
}
}
3. 处理自定义节点,本例中采用了JAXB方法进行处理
Dependency模型, 这里简化了excludes等不定属性的处理
package demo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>1.2</version>
<scope>runtime</scope>
</dependency>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "dependency", namespace = "http://maven.apache.org/POM/4.0.0")
public class Dependency {
@XmlElement(namespace = "http://maven.apache.org/POM/4.0.0")
private String groupId;
@XmlElement(namespace = "http://maven.apache.org/POM/4.0.0")
private String artifactId;
@XmlElement(namespace = "http://maven.apache.org/POM/4.0.0")
private String version;
@XmlElement(namespace = "http://maven.apache.org/POM/4.0.0")
private String scope;
......(省略getter/setter)
}
自定义事件的处理
public class DependencyEvent implements XMLEvent {
public static final int DEPENDENCY_EVENT = 10000;
private Dependency dependency;
.......(省略)
public Dependency getDependency() throws JAXBException, XMLStreamException {
JAXBContext jc = JAXBContext.newInstance(Dependency.class);
Unmarshaller u = jc.createUnmarshaller();
dependency = (Dependency) u.unmarshal(getNode());
return dependency;
}
}
附上简单的eclipse工程代码
分享到:
相关推荐
2. **设置事件处理器**:通过`SAXReader`的`setDocumentHandler`方法设置自定义的`DocumentHandler`实现类,以处理XML事件。 3. **解析XML文件**:调用`read`方法,传入XML文件的路径,解析器开始工作,触发事件...
这个实例展示了如何使用StAX解析XML并将其数据写入目标系统。 总结来说,Kettle的XML Input Stream (StAX) 提供了一种高效、内存友好的方式来处理XML数据。通过合理配置,我们可以轻松地从XML文件中提取数据,然后...
STAX的核心理念是事件驱动,即解析XML时,每遇到一个XML元素或属性,都会触发一个相应的事件,程序通过响应这些事件来处理XML数据。与DOM(Document Object Model)不同,STAX不需要一次性加载整个XML文档到内存,...
在实际开发中,使用STAX时,开发者首先需要通过`XMLInputFactory`获取一个`XMLStreamReader`,然后遍历XML事件并根据需要进行处理。相反,如果要生成XML,可以通过`XMLOutputFactory`获取`XMLStreamWriter`,然后...
- 如何使用DOM、SAX或StAX解析XML - 如何处理XML中的命名空间 - 如何在Java对象和XML之间进行映射(如JAXB) 在实践中,你可能还会遇到编码问题、XML验证(使用DTD或XSD)、XPath用于查询XML数据,以及XML的序列化...
StAX是另一种流式API,允许程序通过迭代器逐个读取XML事件。与SAX不同,StAX允许程序员通过拉取模型控制解析流程,提供了更灵活的处理方式。StAX在处理大型XML文件时内存效率高,且比SAX编程更加直观。 4. JAXB...
在后续的系列文章中,通常会进一步探讨基于事件迭代器的API,包括如何使用XMLEventReader处理各种XML事件,以及如何利用这些事件对象来构建更复杂的XML处理逻辑。同时,也会探讨如何在实际的业务应用程序中有效地...
例如,使用DOM解析XML: ```java DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ...
3. **解析XML**:在解析XML时,可以使用STAX的`XMLStreamReader`来逐事件地处理XML流。结合JAXB,我们可以通过`Unmarshaller`接口将事件转换回Java对象。 4. **事件驱动的解析**:STAX的事件驱动模型允许开发者选择...
以下是一些关于解析XML文件的知识点: 1. XML结构: - 根元素:XML文档必须有一个根元素,所有其他元素都包含在这个根元素内。 - 元素:XML中的基本单位,用尖括号 `< >` 包围,如 `<book>`。 - 属性:元素可以...
1. **解析XML**:DOM4J支持使用DOM、SAX或StAX解析器读取XML文件,其中DOM是将整个XML文档加载到内存中,适用于小型文件;SAX是事件驱动的解析,适用于大文件;而StAX则提供了一种更高效的方式,通过迭代器逐个处理...
在本文中,我们将深入探讨如何解析XML文件,特别是针对街道地址的XML文档。 XML的基本结构由元素、属性、文本内容、命名空间、处理指令以及注释等组成。元素是XML文档的核心,它们定义了数据的结构。例如,在街道...
在Java中,使用DOM解析XML的基本步骤包括: 1. 加载XML文档:使用`javax.xml.parsers.DocumentBuilderFactory`类创建一个实例,并调用其`newDocumentBuilder()`方法生成`DocumentBuilder`对象。 2. 解析XML:使用`...
具体实现过程包括创建解析器、设置解析器属性(如命名空间处理)、解析XML文件、遍历DOM树或处理SAX或StAX事件、使用XPath查询以及进行错误处理等步骤。在实际项目中,选择哪种解析方式取决于文档大小、内存限制、...
然后,使用`javax.xml.bind.JAXBContext`和`Unmarshaller`解析XML。 ```java @XmlRootElement(name = "root") public class MyData { // 定义与XML元素对应的字段,并使用@XmlElement等注解 } JAXBContext ...
本篇文章将深入探讨XML的学习及多种解析XML文件的方法。 首先,理解XML的基本结构至关重要。XML文档由元素(Elements)、属性(Attributes)、文本(Text)、注释(Comments)等组成。元素是XML文档的核心,它们...
- 解析XML文件:使用`XMLReader`的`parse()`方法解析XML文件。 - 处理事件:在事件处理器的`startElement()`、`endElement()`、`characters()`等方法中编写代码,对XML数据进行处理。 3. DOM与SAX比较: - DOM适合...
例如,你可以使用`javax.xml.parsers.DocumentBuilderFactory`和`javax.xml.parsers.DocumentBuilder`创建DOM解析器,然后调用`parse()`方法解析XML文件。DOM解析适用于小型或中型XML文件,因为大型文件可能导致内存...
3. **加载XML文件**:使用解析器的`parse()`方法加载并解析XML文件到`Document`对象。 4. **获取所需节点**:通过`getElementsByTagName()`等方法查找文档中的特定节点。 5. **遍历节点**:遍历找到的节点列表,提取...