`
XmKevinChen
  • 浏览: 86112 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

使用StAX事件定义解析大XML

    博客分类:
  • J2SE
阅读更多

首先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工程代码

 

0
0
分享到:
评论

相关推荐

    dom4j基于事件流解析大XML的文件 示例

    2. **设置事件处理器**:通过`SAXReader`的`setDocumentHandler`方法设置自定义的`DocumentHandler`实现类,以处理XML事件。 3. **解析XML文件**:调用`read`方法,传入XML文件的路径,解析器开始工作,触发事件...

    kettle转换xml(XML Input Stream (StAX))

    这个实例展示了如何使用StAX解析XML并将其数据写入目标系统。 总结来说,Kettle的XML Input Stream (StAX) 提供了一种高效、内存友好的方式来处理XML数据。通过合理配置,我们可以轻松地从XML文件中提取数据,然后...

    stax-api-1.0.1 java 操作 xml 文件 一个很好用的包

    STAX的核心理念是事件驱动,即解析XML时,每遇到一个XML元素或属性,都会触发一个相应的事件,程序通过响应这些事件来处理XML数据。与DOM(Document Object Model)不同,STAX不需要一次性加载整个XML文档到内存,...

    stax-api.jar

    在实际开发中,使用STAX时,开发者首先需要通过`XMLInputFactory`获取一个`XMLStreamReader`,然后遍历XML事件并根据需要进行处理。相反,如果要生成XML,可以通过`XMLOutputFactory`获取`XMLStreamWriter`,然后...

    java大作业xml解析

    - 如何使用DOM、SAX或StAX解析XML - 如何处理XML中的命名空间 - 如何在Java对象和XML之间进行映射(如JAXB) 在实践中,你可能还会遇到编码问题、XML验证(使用DTD或XSD)、XPath用于查询XML数据,以及XML的序列化...

    Java解析XML四种方式

    StAX是另一种流式API,允许程序通过迭代器逐个读取XML事件。与SAX不同,StAX允许程序员通过拉取模型控制解析流程,提供了更灵活的处理方式。StAX在处理大型XML文件时内存效率高,且比SAX编程更加直观。 4. JAXB...

    java使用stax技术操作XML文档.doc

    在后续的系列文章中,通常会进一步探讨基于事件迭代器的API,包括如何使用XMLEventReader处理各种XML事件,以及如何利用这些事件对象来构建更复杂的XML处理逻辑。同时,也会探讨如何在实际的业务应用程序中有效地...

    JAVA调用webservice并解析xml

    例如,使用DOM解析XML: ```java DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ...

    jaxb+stax+demo

    3. **解析XML**:在解析XML时,可以使用STAX的`XMLStreamReader`来逐事件地处理XML流。结合JAXB,我们可以通过`Unmarshaller`接口将事件转换回Java对象。 4. **事件驱动的解析**:STAX的事件驱动模型允许开发者选择...

    解析XML文件例子

    以下是一些关于解析XML文件的知识点: 1. XML结构: - 根元素:XML文档必须有一个根元素,所有其他元素都包含在这个根元素内。 - 元素:XML中的基本单位,用尖括号 `&lt; &gt;` 包围,如 `&lt;book&gt;`。 - 属性:元素可以...

    dom4解析xml需要的包

    1. **解析XML**:DOM4J支持使用DOM、SAX或StAX解析器读取XML文件,其中DOM是将整个XML文档加载到内存中,适用于小型文件;SAX是事件驱动的解析,适用于大文件;而StAX则提供了一种更高效的方式,通过迭代器逐个处理...

    解析地址XML文件

    在本文中,我们将深入探讨如何解析XML文件,特别是针对街道地址的XML文档。 XML的基本结构由元素、属性、文本内容、命名空间、处理指令以及注释等组成。元素是XML文档的核心,它们定义了数据的结构。例如,在街道...

    解析XML所需的jar dom.jar

    在Java中,使用DOM解析XML的基本步骤包括: 1. 加载XML文档:使用`javax.xml.parsers.DocumentBuilderFactory`类创建一个实例,并调用其`newDocumentBuilder()`方法生成`DocumentBuilder`对象。 2. 解析XML:使用`...

    xml解析例子得到各个节点信息

    具体实现过程包括创建解析器、设置解析器属性(如命名空间处理)、解析XML文件、遍历DOM树或处理SAX或StAX事件、使用XPath查询以及进行错误处理等步骤。在实际项目中,选择哪种解析方式取决于文档大小、内存限制、...

    java生成指定格式的xml和解析对于的xml

    然后,使用`javax.xml.bind.JAXBContext`和`Unmarshaller`解析XML。 ```java @XmlRootElement(name = "root") public class MyData { // 定义与XML元素对应的字段,并使用@XmlElement等注解 } JAXBContext ...

    xml学习,多种解析xml文件的方法

    本篇文章将深入探讨XML的学习及多种解析XML文件的方法。 首先,理解XML的基本结构至关重要。XML文档由元素(Elements)、属性(Attributes)、文本(Text)、注释(Comments)等组成。元素是XML文档的核心,它们...

    XML.rar_XML SAX_XML java_dom xml_java xml_java解析xml

    - 解析XML文件:使用`XMLReader`的`parse()`方法解析XML文件。 - 处理事件:在事件处理器的`startElement()`、`endElement()`、`characters()`等方法中编写代码,对XML数据进行处理。 3. DOM与SAX比较: - DOM适合...

    xml的JAVA解析与格式定义

    例如,你可以使用`javax.xml.parsers.DocumentBuilderFactory`和`javax.xml.parsers.DocumentBuilder`创建DOM解析器,然后调用`parse()`方法解析XML文件。DOM解析适用于小型或中型XML文件,因为大型文件可能导致内存...

    四中最常用的XML文件解析总结.doc

    3. **加载XML文件**:使用解析器的`parse()`方法加载并解析XML文件到`Document`对象。 4. **获取所需节点**:通过`getElementsByTagName()`等方法查找文档中的特定节点。 5. **遍历节点**:遍历找到的节点列表,提取...

Global site tag (gtag.js) - Google Analytics