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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM