<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 20,  comments - 7,  trackbacks - 0

    ?

    J2EE/XML 開發者通常都是使用文檔對象模型 (DOM)API 或簡單的 API for XML(SAX) API 來分析 XML 文檔。然而,這些 API 都有其缺點。其中, DOM API 的缺點之一是消耗大量的內存,因為在該 XML 文檔可以被導航之前,必須創建一個完整的 XML 文檔的內存結構。而 SAX API 的缺點在于,它實例了一種推分析模型 API ,其中分析事件是由分析器生成的。比較之下, StAX 則是基于一種拉分析模型。在本文中,你將首先創建你自己的 XML 文檔,然后學習使用各種不同方法來對之進行分析;最后,我們使用事件生成的 StAX 拉方法。

    一、 Push 推分析之于拉分析 Pull

    ?



      比較于推分析,拉分析具有如下一些優點:

       1. 在拉分析中,事件是由分析應用程序生成的,因此把分析規則提供到客戶端而不是分析器。

       2. 拉分析的代碼更簡單并且它比推分析有更少的庫。

       3. 拉分析客戶端能同時讀多個 XML 文檔。

       4. 拉分析允許你過濾 XML 文檔并且跳過分析事件。

    二、了解 StAX


    針對于 XML 的流式 API(StAX) ,是在 2004 3 月的 JSR 173 規范中引入,這是一種針對 XML 的流式拉分析 API StAX JDK 6.0 提供的一種新特征,你可以從此處下載它的測試版本試用。

    一個推模型分析器不斷地生成事件,直到 XML 文檔被完全分析結束。但是,拉分析由應用程序進行調整;因此,分析事件是由應用程序生成的。這意味著,使用 StaX ,你可以推遲分析 - 在分析時跳過元素并且分析多個文檔。在使用 DOM API 的時候,你必須把整個的 XML 文檔分析成一棵 DOM 結構,這樣也就降低了分析效率。而借助于 StAX ,在分析 XML 文檔時生成分析事件。有關于 StAX 分析器與其它分析器的比較在此不多介紹。

    StAX API
    的實現是使用了 Java Web 服務開發( JWSDP 1.6 ,并結合了 Sun Java 流式 XML 分析器 (SJSXP)- 它位于 javax.xml.stream 包中。 XMLStreamReader 接口用于分析一個 XML 文檔,而 XMLStreamWriter 接口用于生成一個 XML 文檔。 XMLEventReader 負責使用一個對象事件迭代子分析 XML 事件 - 這與 XMLStreamReader 所使用的光標機制形成對照。本教程將基于 JDK 6.0 中的 StAX 實現來完成對一個 XML 文檔的分析。

    其實, StaX 僅僅是 JDK 6.0 所提供的 XML 新特征之一。新的 JDK 6.0 還提供了對針對于 XML-Web 服務的 Java 架構( JAX-WS 2.0 ,針對于 XML 綁定的 Java API(JAXB) 2.0 XML 數字簽名 API 的支持,甚至還支持 SQL:2003 'XML' 數據類型。

    三、安裝

    ?

      如果你正在使用 JDK 6.0 ,那么默認情況下, StAX API 位于 Classpath 中。如果你在使用 JWSDP 1.6 ,請把 JWSDP 1.6 StAX API 添加到 classpath 中。

    ?

    jsr173_api.jar sjsxp.jar 添加到 CLASSPATH 變量中。在 <jwsdp-1.6> 目錄下安裝 JWSDP 1.6 Jsr173_api.jar 相應于 JSR-173 API JAR Sjsxp.jar 相應于 SJXSP 實現 JAR

    ?

    四、使用 XMLStreamWriter 進行寫操作

    ?

    ?

      首先,你要創建將待分析的 XML 文檔。由 StAX XMLStreamWriter 生成 XML 。然而, XMLStreamWriter 的一個限制是,它不一定會生成良構的文檔 - 而且生成的文檔也不一定是有效的。你需要確保生成的 XML 文檔是良構的。列表 1 是一個由 XMLStreamWriter 生成的原始 XML 文檔的示例。

      在此,你試圖使用 XMLStreamWriter API 生成列表 1 中的 catalog.xml 。在本節中的代碼片斷節選自 XMLWriter.java 應用程序,顯示于列表 2 中。首先,你將導入 StAX 包類,請參考下列編碼:

    import javax.xml.stream.*;
    import javax.xml.stream.events.*;
    import javax.xml.stream.XMLOutputFactory;
      

    // 首先你必須創建一個新的 XMLOutputFactory
    XMLOutputFactory outputFactory=XMLOutputFactory.newInstance();


    //
    接下來,創建一個 FileWriter 以輸出 XML 文檔 - 它將被生成到一個 XML 文件中:
    FileWriter output=new FileWriter(new File("C:/STAX/catalog.xml"));

    // 接下來,創建一個 XMLStreamWriter
    XMLStreamWriter XMLStreamWriterr=outputFactory.createXMLStreamWriter(output);

    // 添加要在 XML 聲明中指定的編碼和版本(記住,指定的編碼并不是生成的 XML 文檔的編碼)。如果你需要指定 XML 文檔的編碼,該怎么辦呢?當從一個 XMLOutputFactory 對象創建一個 XMLStreamWriter 對象時,你會這樣做:

    XMLStreamWriter.writeStartDocument("UTF-8"
    "1.0");

    // 使用 writeComment() 方法以輸出一個注釋:
    XMLStreamWriter.writeComment("A OReilly Journal Catalog");

    // 使用 writeProcessingInstruction() 方法以輸出一條處理指令:
    XMLStreamWriter.writeProcessingInstruction("catalog"
    "journal='OReilly'");

    // 使用 writeStartElement() 方法以輸出 'catalog' 元素的開始(元素前綴和命名空間 URI 也可以在這個方法中指定的):
    XMLStreamWriter.writeStartElement("journal"
    "catalog" "http://OnJava.com/Journal");


    //
    使用 writeNamespace() 方法以添加 'journal' 命名空間聲明(命名空間前綴和命名空間 URI 也是在這個方法中指定的):
    XMLStreamWriter.writeNamespace("journal"
    "http://OnJava.com/Journal");

    ?

    // 再次使用 writeNamespace() 方法添加 xsi 命名空間:
    XMLStreamWriter.writeNamespace("xsi"
    "http://www.w3.org/2001/XMLSchema-instance");


    //
    使用 writeAttribute() 方法添加 xsi:namespaceSchemaLocation 屬性:
    XMLStreamWriter.writeAttribute("xsi:noNamespaceSchemaLocation"
    "file://c:/Schemas/catalog.xsd");


    //
    使用 writeAttribute() 方法添加 'publisher' 屬性:
    XMLStreamWriter.writeAttribute("publisher"
    "OReilly");

    ?

    // 輸出 'journal' 元素的開始。當增加一個新元素時,前一個元素的 '>' 括號也被添加上:
    XMLStreamWriter.writeStartElement("journal"
    "journal" "http:
    //OnJava.com/Journal");


    //
    使用 writeAttribute() 方法以添加 'date' 'title' 屬性。然后,使用 writeElement() 方法以添加 'article' 'title' 元素。然后,使用 writeCharacters() 方法輸出 'title' 元素的文本:
    XMLStreamWriter.writeCharacters("Data Binding with XMLBeans");

    // 任何包含文本或子元素的元素都要有一個結束標簽。使用 writeEndElement() 元素來添加 'title' 元素的結束標簽:
    XMLStreamWriter.writeEndElement();

    // 添加 'author' 元素和 'journal' 元素的結束標簽。在 writeEndElement() 方法中,不必要指定元素前綴和命名空間 URI 。以類似方式添加另一個 'journal' 元素。然后,添加 'catalog' 元素的結束標簽。最后,輸出緩沖的數據:

    XMLStreamWriter.flush();

    // 最后一步,關閉 XMLStreamWriter
    XMLStreamWriter.close();

    ?

    // 這就是生成 catalog.xml 的過程。

    源碼中的列表 2 展示了完整的 Java 應用程序 -XMLWriter.java 。這個應用程序可以作為一個命令行應用程序運行或在一種例如 Eclipse 這樣的 IDE 中運行。

    ?

    五、使用 XMLStreamReader 進行分析

    ?

    ?

    通過使用 XMLStreamReader API 分析列表 1 中的文檔,我們來詳細分析一下其工作原理。 XMLStreamReader 使用一種光標分析 XML 文檔。它的接口包含一個 next() 方法 - 由它分析下一個分析事件。 getEventType() 方法返回事件類型。后面的代碼片斷來自于 XMLParser.java 應用程序,詳見列表 3

    在這個 XMLParser.java 應用程序中,首先,你要導入 StAX 類:

    import javax.xml.stream.*;
    import javax.xml.stream.events.*;
    import javax.xml.stream.XMLInputFactory;

    // 創建一個 XMLInputFactory ,由此你會得到一個 XMLStreamReader
    XMLInputFactory inputFactory=XMLInputFactory.newInstance();

    // 創建一個 InputStream ,作為一個輸入流,它描述了將被分析的文件。另外,還要從前面創建的 XMLInputFactory 對象中創建一個 XMLStreamReader
    InputStream input=new FileInputStream(new File("C:/STAX/catalog.xml"));

    XMLStreamReader xmlStreamReader =inputFactory.createXMLStreamReader(input);

    // 如果更多分析事件可用, hasNext() 方法返回 true 。然后,使用 next() 方法獲得下一個分析事件:
    int event=xmlStreamReader.next();

    比較于 SAX 分析, StAX 分析的優點是,一個分析事件可以被跳過 - 通過調用 next() 方法 ,詳見下面的代碼。例如,如果分析事件類型為 ENTITY_DECLARATION ,那么開發者可以決定是要從當前事件中獲得事件信息,還是檢索下一個事件:

    If(event.getEventType()==XMLStreamConstants.ENTITY_DECLARATION){
    ?????????????? int event=xmlStreamReader.next();
    }

    通過不調用 next() 方法,分析也可以被推遲。 next() 方法返回 int ,它代表了一個分析事件 - 通過使用一個 XMLStreamConstants 常量指定。

    XMLStreamReader
    所返回的不同的事件類型列舉于表格1中。

    事件類型

    描述

    START_DOCUMENT

    一個文檔的開始

    START_ELEMENT

    一個元素的開始

    ATTRIBUTE

    一個元素屬性

    NAMESPACE

    一個命名空間聲明

    CHARACTERS

    字符可以是文本,或是一個空格

    COMMENT

    一個注釋

    SPACE

    可忽略的空格

    PROCESSING_INSTRUCTION

    處理指令

    DTD

    一個 DTD

    ENTITY_REFERENCE

    一個實體參考

    CDATA

    Cdata

    END_ELEMENT

    結束元素

    END_DOCUMENT

    結束文檔

    ENTITY_DECLARATION

    一個實體聲明

    NOTATION_DECLARATION

    一個標志聲明

    ?

    表格 1.XMLStreamReader 事件

    ?

    ?

    這些不同的分析事件能夠使你獲得 XML 文檔中的數據和元數據。如果分析事件類型是 START_DOCUMENT ,那么你將使用 getEncoding() 方法獲得 XML 文檔中的指定編碼,而你將使用 getVersion() 方法返回 XML 文檔的 XML 版本。


    同樣,如果你在使用一個 START_ELEMENT 事件類型工作,那么你將使用 getPrefix() 方法來返回元素前綴并且使用 getNamespaceURI 來返回元素前綴命名空間或默認命名空間。為了獲得元素的本地命名,你將使用 getLocalName() 方法并且使用 getAttributesCount() 方法獲得屬性數目。你將使用 getAttributePrefix(i) 方法得到一個指定的屬性索引 i 的屬性前綴,而使用 getAttributeNamespace(i) 方法取得屬性命名空間。使用 getAttributeLocalName(i) 方法獲得屬性本地命名,使用 getAttributeValue(i) 方法獲得屬性值。如果事件類型是 CHARACTERS COMMENT ,則使用 getText() 方法獲得相應的文本。

    列表 4 顯示了示例 XML 文檔, catalog.xml 的分析輸出結果。

    列表 3 顯示了用于分析 XML 文檔的 Java 應用程序。你可以從命令行上或在一種例如 Eclipse 這樣的 IDE 中來運行該應用程序。記住:如果你沒有首先運行 XMLWriter.java 應用程序而運行 XMLParser.java( 見源碼中的列表 2) ,那么你需要把 catalog.xml( 見源碼中的列表 1) 復制到 C:/StAX 目錄下。

    ?

    ?

    六、使用 XMLEventReader 進行分析

    ?

    本節將向你展示如何使用 XMLEventReader 來分析 catalog.xml XMLEventReader 接口使用一個事件對象迭代算子分析一個 XML 文檔;通過這種方式,一個 XML 事件生成一個 XMLEvent 對象。 XMLEventReader 類似于 XMLStreamReader- 分析事件是由 StAX 分析器生成的。然而, XMLEventReader XMLStreamReader 有一個優點:通過使用 XMLEventReader ,一個應用程序可以使用 peek() 方法來 " 偷看 " 下一個事件,而不必從流中讀取事件。這樣,一個應用程序客戶端可以決定是否有必要分析下一個事件。 本節中的代碼片斷節選自 XMLEventParser.java 應用程序,請參見列表 5

    首先,導入 StAX 類:

    import javax.xml.stream.*;
    import javax.xml.stream.events.*;
    import javax.xml.stream.XMLInputFactory;
      接下來,創建一個 XMLInputFactory ,由它獲得一個 XMLEventReader 對象:

    XMLInputFactory inputFactory=XMLInputFactory.newInstance();
    InputStream input=new FileInputStream(new File("C:/STAX/catalog.xml"));
    XMLEventReader xmlEventReader =inputFactory.createXMLEventReader(input);
      在 StAX 中, XML 文檔事件是通過 XMLEvent 對象描述的。使用 nextEvent() 方法來遍歷 XMLEventReader 對象以獲得下一個事件:

    XMLEvent event=xmlEventReader.nextEvent();
      使用 getEventType() 方法來獲得事件類型 ( 請參考表格1 ) XMLEvent 接口還提供布爾方法來獲得事件類型。例如, isStartDocum ent() 返回 true ,如果事件是開始文檔類型。在下列代碼中,事件是開始元素類型,因此一個 StartElement 對象可以從這個 XMLEvent 接口獲得:

    if(event.isStartElement()){
      StartElement startElement=event.asStartElement();
    }
      使用 getAttributes() 方法獲得元素屬性:

    Iterator attributes=startElement.getAttributes();
      這個 Iterator 描述了一個 javax.xml.stream.events.Attribute 對象。使用 next() 方法遍歷該 Iterator

    Attribute attribute=(javax.xml.stream.events.Attribute)(attributes.next());
      最后,使用 getName() 方法獲得屬性命名,使用 getValue() 方法獲得屬性值。


    列表 5 顯示出分析該 XML 文檔的 Java 應用程序。應用程序 XMLEventReader 可以作為一個命令行應用程序運行,或在一種例如 Eclipse 這樣的 IDE 中運行。記住:如果你運行 XMLWriter.java XMLParser.java 應用程序而不首先運行 XMLEventParser.java 應用程序,那么你將需要把 catalog.xml 復制到 C:/StAX 目錄下。

    最終,基于拉的事件生成把事件規則提供到分析器應用程序而不是提供到分析器。

    ?

    posted on 2006-09-17 22:24 Lizzie 閱讀(434) 評論(1)  編輯  收藏 所屬分類: 專業積木

    FeedBack:
    # re: 在JDK 6.0中基于StAX分析XML數據
    2009-11-23 07:05 | anon
    you might also want to look at vtd-xml, the latest and most advanced XML processing API available today

    http://vtd-xml.sf.net  回復  更多評論
      

    <2009年11月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    293012345

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    文章分類

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产黄色片在线免费观看| 国产高清对白在线观看免费91| 亚洲第一成年网站大全亚洲| 亚洲国产精品无码久久SM| 亚洲色精品88色婷婷七月丁香| 亚洲情侣偷拍精品| 亚洲无码黄色网址| 亚洲综合av永久无码精品一区二区 | 国产亚洲精aa成人网站| 成人亚洲性情网站WWW在线观看| 国产乱辈通伦影片在线播放亚洲| JLZZJLZZ亚洲乱熟无码| 亚洲一区视频在线播放| 亚洲深深色噜噜狠狠爱网站| 国产精一品亚洲二区在线播放| 亚洲AV无码欧洲AV无码网站| 久久久亚洲AV波多野结衣| 亚洲熟妇无码爱v在线观看| 亚洲国产综合在线| 亚洲综合色婷婷在线观看| 色偷偷尼玛图亚洲综合| 欧洲乱码伦视频免费国产| 中国极品美軳免费观看| 免费看又黄又无码的网站| 免费精品国产日韩热久久| 精品国产免费观看一区| 亚洲国产精品丝袜在线观看| 亚洲爆乳无码一区二区三区| 亚洲精彩视频在线观看| 亚洲人成网站色7799| 免费无码又爽又黄又刺激网站| a毛片在线看片免费| 97免费人妻无码视频| 免费黄色毛片视频| 亚洲精品无码专区2| 亚洲天天做日日做天天看| 亚洲综合中文字幕无线码| 羞羞漫画小舞被黄漫免费| 日本在线免费播放| 成人人免费夜夜视频观看| 亚洲一级特黄无码片|