XML编程总结(五)——使用StAX接口操作xml

(五)使用StAX接口操作xml

StAX,全称Streaming API for XML,一种全新的,基于流的JAVA XML解析标准类库。其最终版本于 2004 年 3 月发布,并成为了 JAXP 1.4(将包含在即将发布的 Java 6 中)的一部分。在某种程度上来说,StAX与SAX一样是基于XML事件的解析方式,它们都不会一次性加载整个XML文件。但是它们之间也有很大的不同。

StAX和SAX的区别——拉式解析器和推式解析器的区别

虽然StAX与SAX一样基于XML事件解析,相比于DOM将整个XML加载进内存来说效率高。不同的是,StAX在在处理XML事件的方式上使得应用程序更接近底层,所以在效率上比SAX更优秀。

使用SAX时,我们知道XML事件是由解析器调用开发人员编写的回调方法来处理的,也就是说应用程序是被动于解析器的。应用程序只能被动的等待解析器将XML事件推送给自己处理,对于每一种事件都需要在解析开始之前就做好准备。这种方式被称为“推(push)”。而StAX正好相反,StAX采用一种“拉(pull)”的方式,由应用程序主动从解析器中获取当前XML事件然后根据需求处理(保存或者忽略)。StAX使得应用程序掌握了主动权,可以简化调用代码来准确地处理它预期的内容,或者发生意外时停止解析。此外,由于该方法不基于处理程序回调,应用程序不需要像使用 SAX 那样模拟解析器的状态。

基于指针的API:

基于指针(Cursor)的 API 允许应用程序把 XML 作为一个标记(或事件)流来处理。在这里,解析器就像一跟指针一样在文件流上前进,应用程序可以跟随解析器从文件的开头一直处理到结尾。这是一种低层 API,尽管效率高,但是没有提供底层 XML 结构的抽象。Cursor API 由两个主要API组成,XMLStreamReader和XMLStreamWriter,分别由XMLInputStreamFactory和XMLOutputStreamFactory获取

基于迭代器的API:

基于迭代器的API允许应用程序把 XML 作为一系列事件对象来处理,每个对象和应用程序交换 XML 结构的一部分。应用程序只需要确定解析事件的类型,将其转换成对应的具体类型,然后利用其方法获得属于该事件的信息。基于事件迭代器的方法具有一个基于指针的方法不具备的重要优点。通过将解析器事件变成一级对象,从而让应用程序可以采用面向对象的方式处理它们。这样做有助于模块化和不同应用程序组件之间的代码重用。Iterator API 由两个主要API组成,XMLEventReader和XMLEventWriter,分别由XMLInputStreamFactory和XMLOutputStreamFactory获取

测试代码

  1 public class StAXTest {
  2     private InputStream is;
  3
  4     @Before
  5     public void setUp() throws Exception{
  6         is=StAXTest.class.getClassLoader()
  7                 .getResourceAsStream("books.xml");
  8     }
  9
 10     /**
 11      * 基于指针的方式读取xml文档——XMLStreamReader
 12      * @throws Exception
 13      */
 14     @Test
 15     public void testRetrieveByCursor() throws Exception{
 16         //创建读取流工厂对象
 17         XMLInputFactory factory = XMLInputFactory.newInstance();
 18         //创建基于指针的读取流对象
 19         XMLStreamReader streamReader = factory.createXMLStreamReader(is);
 20         //用指针迭代
 21         while(streamReader.hasNext()){
 22             //事件的ID
 23             int eventId=streamReader.next();
 24
 25             switch (eventId) {
 26             case XMLStreamConstants.START_DOCUMENT:
 27                 System.out.println("start docmuent");
 28                 break;
 29
 30             case XMLStreamConstants.START_ELEMENT:
 31                 System.out.println("<"+streamReader.getLocalName()+">");
 32                 for(int i=0;i<streamReader.getAttributeCount();i++){
 33                     System.out.println(streamReader.getAttributeLocalName(i)+
 34                             "="+streamReader.getAttributeValue(i));
 35                 }
 36                 break;
 37
 38             case XMLStreamConstants.CHARACTERS:
 39                 if(streamReader.isWhiteSpace()){
 40                     break;
 41                 }
 42                 System.out.println(streamReader.getText());
 43                 break;
 44             case XMLStreamConstants.END_ELEMENT:
 45                 System.out.println("</"+streamReader.getLocalName()+">");
 46
 47                 break;
 48             case XMLStreamConstants.END_DOCUMENT:
 49                 System.out.println("end docmuent");
 50                 break;
 51             default:
 52                 break;
 53             }
 54         }
 55     }
 56
 57     /**
 58      * 基于迭代器的方式读取xml文档——XMLEventReader
 59      * @throws Exception
 60      */
 61     @Test
 62     public void testRetrieveByIterator() throws Exception{
 63         //创建读取流工厂对象
 64         XMLInputFactory factory = XMLInputFactory.newInstance();
 65         //创建基于迭代器(事件流对象)的流对象
 66         XMLEventReader eventReader = factory.createXMLEventReader(is);
 67         //迭代xml文档
 68         while (eventReader.hasNext()) {
 69             //得到具体的 事件对象,就是引发事件的对象(可以是元素节点、文本节点、属性节点)
 70             XMLEvent event = eventReader.nextEvent();
 71
 72             switch (event.getEventType()) {
 73             case XMLStreamConstants.START_DOCUMENT:
 74                 System.out.println("start docmuent");
 75                 break;
 76
 77             case XMLStreamConstants.START_ELEMENT:
 78                 //将事件对象可以转换为元素节点对象
 79                 StartElement element = (StartElement) event;
 80                 System.out.println("<" + element.getName().getLocalPart() + ">");
 81                 for (Iterator it = element.getAttributes(); it.hasNext();) {
 82                     Attribute attr = (Attribute) it.next();
 83                     System.out.println(attr.getName().getLocalPart() + "=" + attr.getValue());
 84                 }
 85                 break;
 86
 87             case XMLStreamConstants.CHARACTERS:
 88                 //将事件对象可以转换成文本节点
 89                 Characters charData = (Characters) event;
 90                 if (charData.isIgnorableWhiteSpace() && charData.isWhiteSpace()) {
 91                     break;
 92                 }
 93                 System.out.println(charData.getData());
 94                 break;
 95             case XMLStreamConstants.END_ELEMENT:
 96                 //将事件对象可以转换为元素节点对象
 97                 EndElement endElement = (EndElement) event;
 98                 System.out.println("</" + endElement.getName().getLocalPart() + ">");
 99
100                 break;
101             case XMLStreamConstants.END_DOCUMENT:
102                 System.out.println("end docmuent");
103                 break;
104             default:
105                 break;
106             }
107         }
108     }
109
110     /**
111      * 基于指针的API输出流——XMLStreamWriter
112      * @throws Exception
113      */
114     @Test
115     public void testCreateByCursor() throws Exception{
116         //创建输出流对象工厂
117         XMLOutputFactory factory = XMLOutputFactory.newInstance();
118         //创建输出流对象
119         XMLStreamWriter streamWriter = factory.createXMLStreamWriter(System.out);
120         //创建xml文档,根据对象方法创建对象元素
121         streamWriter.writeStartDocument();
122         //book start
123         streamWriter.writeStartElement("book");
124         streamWriter.writeAttribute("category", "CODING");
125
126         streamWriter.writeStartElement("title");
127         streamWriter.writeCharacters("Java Coding");
128         streamWriter.writeEndElement();
129
130         streamWriter.writeStartElement("author");
131         streamWriter.writeCharacters("lisa");
132         streamWriter.writeEndElement();
133
134         streamWriter.writeStartElement("year");
135         streamWriter.writeCharacters("2013");
136         streamWriter.writeEndElement();
137
138         streamWriter.writeStartElement("price");
139         streamWriter.writeCharacters("79.9");
140         streamWriter.writeEndElement();
141
142         //book end
143         streamWriter.writeEndElement();
144
145         streamWriter.writeEndDocument();
146         streamWriter.flush();
147     }
148
149     /**
150      * 基于迭代器的API输出流——XMLEventWriter
151      * @throws Exception
152      */
153     @Test
154     public void testCreateByIterator() throws Exception{
155         //创建输出流对象工厂
156         XMLOutputFactory factory = XMLOutputFactory.newInstance();
157         //创建输出流对象
158         XMLEventWriter eventWriter = factory.createXMLEventWriter(System.out);
159         //创建xml文档,根据对象方法创建对象元素
160         eventWriter.add(new StartDocumentEvent());
161         eventWriter.add(new StartElementEvent(new QName("book")));
162
163         eventWriter.add(new StartElementEvent(new QName("title")));
164         eventWriter.add(new CharacterEvent("Java Coding"));
165         eventWriter.add(new EndElementEvent(new QName("title")));
166
167         eventWriter.add(new StartElementEvent(new QName("author")));
168         eventWriter.add(new CharacterEvent("rilay"));
169         eventWriter.add(new EndElementEvent(new QName("author")));
170
171         eventWriter.add(new StartElementEvent(new QName("year")));
172         eventWriter.add(new CharacterEvent("2008"));
173         eventWriter.add(new EndElementEvent(new QName("year")));
174
175         eventWriter.add(new StartElementEvent(new QName("price")));
176         eventWriter.add(new CharacterEvent("29.9"));
177         eventWriter.add(new EndElementEvent(new QName("price")));
178
179         eventWriter.add(new EndElementEvent(new QName("book")));
180         eventWriter.add(new EndDocumentEvent());
181         eventWriter.flush();
182     }
183
184 }
时间: 2024-10-14 08:34:20

XML编程总结(五)——使用StAX接口操作xml的相关文章

XML编程总结(三)——使用SAX接口操作xml

(三)使用SAX接口操作xml SAX解析器被称为SAXParser,SAXParser是由javax.xml.parsers.SAXParserFactory创建的.与DOM解析器不同,SAX解析器并不创建XML文档的内存表示,因此会占用更少的内存.SAX解析器通过调用回调方法(事件驱动)将XML文档结构通知客户端,也就是通过调用提供给SAXParser的org.xml.sax.helpers.DefaultHandler处理器内的方法. org.xml.sax.helpers.Default

XML编程总结(二)——使用DOM接口操作xml

(二)使用DOM接口操作xml DOM解析器将整个XML文档加载到内存中,使用DOM模型对XML文档在内存中建模.DOM解析器被称为DocumentBuilder,它位于javax.xml.parsers包下.下面是使用DOM对xml文档进行CRUD操作的演示. 测试类代码:Source和Result接口的使用,将内存中xml模型输出 1 public class DomTest { 2 private Document document; 3 4 @Before 5 public void s

scala编程(五)——基本类型和操作

文本 文本是直接在代码里写常量值的一种方式以.在Scala中并不显式的使用Int或float,而是以文本的方式写成 val 变量. 如果整数文本结束于 L 或者 l,就是 Long 类型,否则就是 Int 类型. 如果浮点数文本以F或f结束,就是Float类型的,否则就是Double类型的. 可选的,Double浮点数文本也可以D或d结尾. 字符文本可以是在单引号之间的任何 Unicode 字符 def main(args: Array[String]): Unit = { val l = 1l

XML编程总结(一)——目录

本系列文章对Java领域中常用的几种操作XML的编程方式进行归纳,归纳的知识属于基础范畴,概括的不全面.主要通过实例操作方法进行演示,原理部分的讲解甚少,如需请查阅详细文档资料.本文分为以下几个部分: (一)JAXP简介 (二)使用DOM接口操作xml (三)使用SAX接口操作xml (四)使用dom4j方式操作xml (五)使用StAX接口操作xml (六)使用JAXB进行java对象和xml格式之间的相互转换 (七)使用XPath对象查询xml文档 (一)JAXP简介 JAXP(Java A

ActionScript 3操作XML 详解

AS3引入了E4X ,它是根据ECMAScript标准处理XML 数据的全新机制.这使得程序员在程序中无缝地操作XML.在AS3中可以使用XML字面值将XML数据直接写入代码,该字面值将被自动解析. 一.AS3中的XML入门 1.可以将XML直接写入代码 public var employeelist:XML=<employeelist> <employee> <name first="Conan" last="O'Brien" /&g

C#操作XML(读XML,写XML,更新,删除节点,与dataset结合等)【转载】

已知有一个XML文件(bookstore.xml)如下: Corets, Eva 5.95 1.插入节点 往节点中插入一个节点: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 XmlDocument xmlDoc=new XmlDocument(); xmlDoc.Load("bookstore.xml"); XmlNode root=xmlDoc.SelectSingleNode("bookstore");//查找

flex操作XML,强力总结帖

初始化XML对象 XML对象可以代表一个XML元素.属性.注释.处理指令或文本元素.在ActionScript 3.0中我们可以直接将XML数据赋值给变量: var myXML:XML =    <order>        <item id='1'>            <menuName>burger</menuName>            <price>3.95</price>        </item>  

Java Stax操作XML简介

使用stax操作xml 非常的简单,它的读取过程像是一个光标在移动.针对不同的节点做不同的处理. 先看一个基于光标的模型处理xml: public class StaxTest { @Test public void test1() { try { // 1.构建XMLStreamReader XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader reader = factory .createXMLSt

[JAVA_开课吧资源]第五周 I/O操作、多线程、网络编程技术

主题一 I/O操作 » 流的概念 在面向对象语言中, 数据的输入和输出都是通过数据流来实现的.数据流是一组有顺序.有起点和终点的字符集合.就好比是两个不同的池子,一个池子中存满了水,而另一个池子中则没有任何的东西,在这两个水池中安放一个管子,水就可以从一个池子流向另一个池子了.在从一个池子向另一个池子输送水的过程中,水扮演的角色就是数据流. [请点击查看更多内容 转自文章] » Stream stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源.在Java的IO中,所有