`
schy_hqh
  • 浏览: 555867 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

使用Stax处理XML

 
阅读更多

java提供的XML处理
Stax处理XML:不会把XML一次性读入
基于光标的查找(使用reader一个一个读)
基于迭代模型的查找
过滤器的使用
XPATH的使用
使用XMLStreamWriter创建xml
使用Transformer更新节点信息


<?xml version="1.0" encoding="UTF-8"?>

<bookstore>

	<book category="COOKING">
		<title lang="en">Everyday Italian</title>
		<author>Giada De Laurentiis</author>
		<year>2005</year>
		<price>30.00</price>
	</book>

	<book category="CHILDREN">
		<title lang="en">Harry Potter</title>
		<author>J K. Rowling</author>
		<year>2005</year>
		<price>29.99</price>
	</book>

	<book category="WEB">
		<title lang="en">XQuery Kick Start</title>
		<author>James McGovern</author>
		<author>Per Bothner</author>
		<author>Kurt Cagle</author>
		<author>James Linn</author>
		<author>Vaidyanathan Nagarajan</author>
		<year>2003</year>
		<price>49.99</price>
	</book>

	<book category="WEB">
		<title lang="en">Learning XML</title>
		<author>Erik T. Ray</author>
		<year>2003</year>
		<price>39.95</price>
	</book>

</bookstore>


基于光标的处理XMLStreamReader
package com.hqh.stax;

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.junit.Test;

public class TestStax {
/**
 * Stax将XML从结构上划分成了若干块
 * 在XMLStreamConstants中定义了若干常量来表示
 * 文档起始:START_DOCUMENT=7
 * 文档结束:END_DOCUMENT=8
 * 元素开始标签:START_ELEMENT=1
 * 元素结束标签:END_ELEMENT=2
 * 元素节点中的内容:CHARACTERS=4
 * 空格:SPACE=6
 * ...
 * 
 */
	@Test
	public void testStax01() {
		XMLInputFactory factory = XMLInputFactory.newInstance();
		InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("books.xml");
		try {
			XMLStreamReader reader = factory.createXMLStreamReader(is);
			while(reader.hasNext()) {
				//获取下一个节点
				int type = reader.next();
				
				if(type==XMLStreamConstants.START_ELEMENT) {//开始元素
					String name = reader.getName().toString();
					//根据name决定是否操纵该节点中的信息
					System.out.println(name);
					if(name.equals("book")) {//输出book定义的属性
						System.out.println(reader.getAttributeName(0)+":"+reader.getAttributeValue(0));
					}
				} else if(type==XMLStreamConstants.CHARACTERS) {//元素中的内容
					System.out.println("\t"+reader.getText().trim());
				} else if(type==XMLStreamConstants.END_ELEMENT) {//结束元素
					System.out.println("/"+reader.getName());
				}
			}
		} catch (XMLStreamException e) {
			e.printStackTrace();
		} finally {
			if(is!=null)
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
	
	/**
	 * 灵活的对xml中关注的节点进行操作
	 */
	@Test
	public void testStax02() {
		XMLInputFactory factory = XMLInputFactory.newInstance();
		InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("books.xml");
		try {
			XMLStreamReader reader = factory.createXMLStreamReader(is);
			while(reader.hasNext()) {
				//获取下一个节点
				int type = reader.next();
				
				//输出每本书的价格
				if(type==XMLStreamConstants.START_ELEMENT) {
					String name = reader.getName().toString();
					//根据name决定是否操纵该节点中的信息
					if(name.equals("title")) {//输出book定义的属性
						System.out.print(reader.getElementText().trim()+":");
					} else if(name.equals("price")) {
						System.out.println(reader.getElementText().trim());
					}
				}
			}
		} catch (XMLStreamException e) {
			e.printStackTrace();
		} finally {
			if(is!=null)
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
}




基于迭代模型的处理XMLEventReader
	/**
	 * 基于迭代的方式XMLEventReader
	 */
	@Test
	public void testStax03() {
		XMLInputFactory factory = XMLInputFactory.newInstance();
		InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("books.xml");
		XMLEventReader reader = null;
		try {
			//创建eventReader
			reader = factory.createXMLEventReader(is);
			int loopCount = 0;
			while(reader.hasNext()) {
				loopCount++;
				//通过event进行迭代
				XMLEvent event = reader.nextEvent();
				if(event.isStartElement()) {
					//将event转换为Element进行操作
					StartElement startElement = event.asStartElement();
					String name = startElement.getName().toString();
					if(name.equals("book")) {
						System.out.print(name+":");
						//获取属性定义
						Attribute attr = startElement.getAttributeByName(new QName("category"));
						if(attr!=null) {
							System.out.println(attr.toString());
						}
					}
				}
			}
			System.out.println("基于迭代模型未使用过滤器共循环"+loopCount+"次");
		} catch (XMLStreamException e) {
			e.printStackTrace();
		} finally {
			if(is!=null)
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			if(reader!=null) {
				try {
					reader.close();
				} catch (XMLStreamException e) {
					e.printStackTrace();
				}
			}
		}
	}

运行结果:

book:category='COOKING'
book:category='CHILDREN'
book:category='WEB'
book:category='WEB'
基于迭代模型未使用过滤器共循环101次



基于迭代的方式,使用过滤器,提高读取效率FilteredReader
/**
	 * 基于迭代的方式,使用过滤器,提高读取效率FilteredReader
	 */
	@Test
	public void testStax04() {
		XMLInputFactory factory = XMLInputFactory.newInstance();
		InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("books.xml");
		XMLEventReader eventReader = null;
		XMLEventReader filterReader = null;
		try {
			//没有过滤器的eventReader
			eventReader = factory.createXMLEventReader(is);
			//创建带有过滤器的eventReader
			filterReader = factory.createFilteredReader(eventReader, new EventFilter() {
				@Override
				public boolean accept(XMLEvent event) {
					//指定不被过滤的类型
					if(event.isStartElement()) {
						String name = event.asStartElement().getName().toString();
						if("book".equals(name)) {
							return true;
						}
					}
					return false;
				}
			});
			int loopCount = 0;
			while(filterReader.hasNext()) {
				loopCount++;
				//通过event进行迭代
				XMLEvent event = filterReader.nextEvent();
				if(event.isStartElement()) {
					//将event转换为Element进行操作
					StartElement startElement = event.asStartElement();
					String name = startElement.getName().toString();
					if(name.equals("book")) {
						System.out.print(name+":");
						//获取属性定义
						Attribute attr = startElement.getAttributeByName(new QName("category"));
						if(attr!=null) {
							System.out.println(attr.toString());
						}
					}
				}
			}
			System.out.println("使用过滤器迭代,共循环"+loopCount+"次!");
		} catch (XMLStreamException e) {
			e.printStackTrace();
		} finally {
			try {
				if(is!=null)
					is.close();
				if(eventReader!=null)
					eventReader.close();
				if(filterReader!=null)
					filterReader.close();
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
	}


运行结果:

book:category='COOKING'
book:category='CHILDREN'
book:category='WEB'
book:category='WEB'
使用过滤器迭代,共循环4次!


使用Stax结合过滤器处理XML对效率的提高非常给力!
分享到:
评论

相关推荐

    使用StAX进行高效的XML处理中文版

    StAX(Streaming API for XML)是一种新的XML解析方式,它提供了一种高效的、基于事件驱动的方式来处理XML文档。相比于DOM(Document Object Model)和SAX(Simple API for XML),StAX在处理大型或复杂XML文档时...

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

    Streaming API for XML (StAX) 是Java中处理XML的一种高效且灵活的标准,相较于DOM和SAX,它在性能和易用性上有显著优势。StAX是JSR-173的一部分,于2004年3月发布,最终被纳入JAXP 1.4,也将在Java 6中得到支持。 ...

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

    在处理XML数据时,Kettle提供了多种方式,其中XML Input Stream (StAX) 是一种高效且灵活的方法。本文将深入探讨如何使用Kettle的XML Input Stream (StAX) 进行XML数据的转换。 首先,XML(Extensible Markup ...

    stax 解析xml demo project

    STAX允许开发者以流式方式处理XML,使得处理大型XML文件时能有效地管理内存,避免一次性加载整个文档导致的资源消耗。本项目“stax 解析xml demo project”是一个使用Eclipse开发的实例,旨在演示如何利用STAX API...

    stax+jaxb进行xml解析

    StAX是一种事件驱动的XML解析API,它允许程序逐个处理XML事件,如开始元素、结束元素、文本等,而不是一次性加载整个文档到内存。这种方式降低了内存使用,提高了处理大型XML文档的效率。Woodstax是StAX的一种实现,...

    用Stax组装及解析XML

    在处理XML文档时,Java提供了多种工具和技术,包括DOM、SAX以及本文将重点讨论的Streaming API for XML(简称StAX)。StAX是一种用于读取和写入XML数据的事件驱动型API,特别适合于处理大型XML文件或在内存有限的...

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

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

    DOM、SAX、DOM4J、JDOM、StAX生成XML并返回XML字符串形式

    为了处理XML文档,有多种解析器可供选择,其中包括DOM、SAX、DOM4J、JDOM和StAX。这些解析器各有特点,适用于不同的场景。下面将详细介绍这些解析器的工作原理以及它们在生成XML并返回XML字符串形式时的应用。 1. ...

    stax-api.jar

    `stax-api.jar`是Java中用于处理XML流的STAX(Streaming API for XML)的API接口库,它提供了与XML数据交互的一套标准化接口。 STAX(Streaming API for XML)是一种低级别的XML解析方法,相比DOM(Document Object...

    Java6.0新特性之StAX--全面解析Java XML分析技术

    StAX提供了一种高效且内存友好的方式来处理XML文档,使得开发者能够在不加载整个XML文档到内存的情况下进行读写操作。这种特性对于处理大型XML文件尤其有用。 StAX是一种事件驱动的XML解析API,它允许程序员通过...

    kettle解析xml多层分组嵌套数据,StAX方法,完整解析案例(包含xml文件以及ktr文件)

    kettle 解析xml数据,xml多层分组嵌套,xml stax方法,完整解析案例使用(包含xml文件以及ktr文件)。ETL大数据迁移,数据清洗。XML Input Stream (StAX) 方法

    java xml 4 种 解析xml 方法 sax jdom dom stAX

    为了处理XML文档,Java提供了多种解析方法,包括SAX(Simple API for XML)、JDOM(Java Document Object Model)、DOM(Document Object Model)以及stAX(Streaming API for XML)。下面将详细介绍这四种解析XML的...

    stax-api 1.0.1

    与DOM(Document Object Model)不同,STAX不是加载整个XML文档到内存中形成一个树形结构,而是通过事件(如开始元素、结束元素、文本等)流式地处理XML,这使得STAX在处理大型XML文件时更为高效。 "stax-api 1.0.1...

    Stax组装及解析XML的例子

    与DOM(Document Object Model)不同,StAX不将整个XML文档加载到内存中,而是通过迭代器模型逐个处理XML事件,如开始元素、结束元素、文本等,从而减少了内存占用,提高了处理大型XML文件的性能。 在给定的例子中...

    有用的Java工具—XML解析工具StAx

    StAX是一种基于事件驱动的解析器,它允许程序员通过逐个处理XML事件(如开始元素、结束元素、文本等)来读取和写入XML文档,这种方式相比DOM(Document Object Model)更加轻量级和高效。 **StAX的优势** 1. **低...

    jaxb+stax+demo

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

    stax-api-1.0-2

    STAX提供了一种流式处理XML文档的方法,与DOM(Document Object Model)相比,它更加高效且内存占用更低。在“stax-api-1.0-2”这个版本中,我们看到了该API的一个稳定版本,它包含了源代码、已编译的JAR文件以及...

    stax-api-1.0.1、stax2-api-3.1.1、woodstox-core-asl-4.1.1

    STAX(Streaming API for XML)是一种用于处理XML的Java API,它提供了事件驱动的解析方式,使得开发者可以高效地读取和写入XML文档。在Java世界中,STAX提供了比DOM(Document Object Model)更高效的处理XML的方式...

Global site tag (gtag.js) - Google Analytics