使用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)