XML之StAX一

XML之StAX(一)

XML之StAX(二)

1.StAX

StAX是绑定在JDK中的,面向流和事件(Stream/Event)的XML解析器。StAX采用的是“pull“方式解析XML,即你的解析方法可以控制什么时候解析器继续向下解析,以及可以在任何位置停止解析。这就像解析方法在从解析器里拉XML事件一样。StAX的这种解析方式,意味着你不得不按照XML文件的元素,逐条移动StAX解析器,这就有点像Iterator或JDBC的ResultSet。StAX有以下特性:

  1. 可以解析XML文件的一部分之后就停止解析;
  2. 可以生成XML文件
  3. 不支持XML模式验证。
同时,StAX提供了两种不同的解析API:
  1. XMLEventReader:像使用Iterator一样。
  2. XMLStreamReader:像使用JDBC的ResultSet一样。

2.面向Event的StAX

2.1XMLEventReader

XMLEventReader提供了一个nextEvent()方法,很像Iterator。通过Event对象,你可以查到你遇到Event的类型(如:element、text、comment等),同时Event element是不可变的。当你迭代到下一个Event时,之前的Event对象仍然被保存着。下面是一个用于测试的XML文件
<?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>

这是一个简单的XMLEventReader使用的例子:
public static void read()throws IOException {
	XMLInputFactory factory = XMLInputFactory.newFactory();
	Reader reader = null;

	try{
		reader = new FileReader("F:\\Codes\\IDEA\\Tools\\data\\xml\\test.xml");
		XMLEventReader eventReader = factory.createXMLEventReader(reader);

		while (eventReader.hasNext()){
			XMLEvent event = eventReader.nextEvent();

			// streamReader.getEventType() == XMLStreamReader.START_ELEMENT equals streamReader.isstartElement()
			if(event.isstartElement()){
				StartElement startElement = event.asstartElement();
				String name = startElement.getName().toString();
				if(!name.equals("bookstore") && !name.equals("book")) {
					System.out.print(name + ": ");
					System.out.println(eventReader.getElementText());
				}
				else if(name.equals("book")){
					System.out.println(startElement.getAttributes().next());
				}
			}
		}
	}
	catch (Exception e){
		e.printstacktrace();
	}
	finally {
		if(reader != null){
			reader.close();
		}
	}
}

当然,在某些情况下,我们只需要得到特定标签的值,那么如果还像上述一样解析就白做和很多无用功。但是,不用担心,我们可以自定义过滤器作用于XMLEventReader,从而得到优化的效果
public static void readFilter()throws IOException{
	XMLInputFactory factory = XMLInputFactory.newFactory();
	InputStream input = null;

	try{
		input = new FileInputStream(new File("F:\\Codes\\IDEA\\Tools\\data\\xml\\test.xml"));
		XMLEventReader reader = factory.createFilteredReader(
				factory.createXMLEventReader(input),new EventFilter() {
					@Override
					public boolean accept(XMLEvent event) {
						if(event.isstartElement()){
							String name = event.asstartElement().getName().toString();
							if(name.equals("title") || name.equals("price")){
								return true;
							}
						}
						return false;
					}
				});

		while (reader.hasNext()){
			XMLEvent event = reader.nextEvent();
			if(event.isstartElement()){
				String name = event.asstartElement().getName().toString();
				System.out.println(name + ": " + reader.getElementText());
			}
		}
	}
	catch (Exception e){
		e.printstacktrace();
	}
	finally {
		if(input != null){
			input.close();
		}
	}
}

2.2XMLEventWriter

XMLEvenWriter是StAX用于将Writer,OutputStream等对象的数据生成XML保存在disk。下面是一个简单的例子:
public static void write(){
	XMLOutputFactory factory = XMLOutputFactory.newFactory();
	XMLEventFactory eventFactory = XMLEventFactory.newFactory();

	try {
		XMLEventWriter writer = factory.createXMLEventWriter(
				new FileWriter("F:\\Codes\\IDEA\\Tools\\data\\xml\\iterator.xml"));
		XMLEvent event = eventFactory.createStartDocument();
		writer.add(event);

		event = eventFactory.createStartElement("test",null,"bookstore");
		writer.add(event);

		event = eventFactory.createStartElement("test","book");
		writer.add(event);
		event = eventFactory.createNamespace("google","http://www.google.com");
		writer.add(event);
		event = eventFactory.createAttribute("category","COmpuTER");
		writer.add(event);

		event = eventFactory.createStartElement("test","author");
		writer.add(event);
		event = eventFactory.createCharacters("Giada De Laurentiis");
		writer.add(event);
		event = eventFactory.createEndElement("test","author");
		writer.add(event);
		event = eventFactory.createEndElement("test","book");
		writer.add(event);
		event = eventFactory.createEndElement("test","bookstore");
		writer.add(event);

		writer.flush();
		writer.close();
	}
	catch (Exception e){
		e.printstacktrace();
	}
}

产生的输出文件
<?xml version="1.0" encoding="UTF-8"?>
<test:bookstore>
    <test:book xmlns:google="http://www.google.com" category="COmpuTER">
        <test:author>Giada De Laurentiis</test:author>
    </test:book>
</test:bookstore>


注意:在使用XMLEventWriter生成XML文件时,必须为每一个元素指定一个前缀(如:例子中的“test”)



文献:

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念