<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 開發(fā)者通常都是使用文檔對象模型 (DOM)API 或簡單的 API for XML(SAX) API 來分析 XML 文檔。然而,這些 API 都有其缺點(diǎn)。其中, DOM API 的缺點(diǎn)之一是消耗大量的內(nèi)存,因?yàn)樵谠?/span> XML 文檔可以被導(dǎo)航之前,必須創(chuàng)建一個(gè)完整的 XML 文檔的內(nèi)存結(jié)構(gòu)。而 SAX API 的缺點(diǎn)在于,它實(shí)例了一種推分析模型 API ,其中分析事件是由分析器生成的。比較之下, StAX 則是基于一種拉分析模型。在本文中,你將首先創(chuàng)建你自己的 XML 文檔,然后學(xué)習(xí)使用各種不同方法來對之進(jìn)行分析;最后,我們使用事件生成的 StAX 拉方法。

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

    ?



      比較于推分析,拉分析具有如下一些優(yōu)點(diǎn):

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

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

       3. 拉分析客戶端能同時(shí)讀多個(gè) XML 文檔。

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

    二、了解 StAX


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

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

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

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

    三、安裝

    ?

      如果你正在使用 JDK 6.0 ,那么默認(rèn)情況下, 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 相應(yīng)于 JSR-173 API JAR Sjsxp.jar 相應(yīng)于 SJXSP 實(shí)現(xiàn) JAR

    ?

    四、使用 XMLStreamWriter 進(jìn)行寫操作

    ?

    ?

      首先,你要?jiǎng)?chuàng)建將待分析的 XML 文檔。由 StAX XMLStreamWriter 生成 XML 。然而, XMLStreamWriter 的一個(gè)限制是,它不一定會(huì)生成良構(gòu)的文檔 - 而且生成的文檔也不一定是有效的。你需要確保生成的 XML 文檔是良構(gòu)的。列表 1 是一個(gè)由 XMLStreamWriter 生成的原始 XML 文檔的示例。

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

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

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


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

    // 接下來,創(chuàng)建一個(gè) XMLStreamWriter
    XMLStreamWriter XMLStreamWriterr=outputFactory.createXMLStreamWriter(output);

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

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

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

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

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


    //
    使用 writeNamespace() 方法以添加 'journal' 命名空間聲明(命名空間前綴和命名空間 URI 也是在這個(gè)方法中指定的):
    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' 元素的開始。當(dāng)增加一個(gè)新元素時(shí),前一個(gè)元素的 '>' 括號也被添加上:
    XMLStreamWriter.writeStartElement("journal"
    "journal" "http:
    //OnJava.com/Journal");


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

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

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

    XMLStreamWriter.flush();

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

    ?

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

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

    ?

    五、使用 XMLStreamReader 進(jìn)行分析

    ?

    ?

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

    在這個(gè) XMLParser.java 應(yīng)用程序中,首先,你要導(dǎo)入 StAX 類:

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

    // 創(chuàng)建一個(gè) XMLInputFactory ,由此你會(huì)得到一個(gè) XMLStreamReader
    XMLInputFactory inputFactory=XMLInputFactory.newInstance();

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

    XMLStreamReader xmlStreamReader =inputFactory.createXMLStreamReader(input);

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

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

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

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

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

    事件類型

    描述

    START_DOCUMENT

    一個(gè)文檔的開始

    START_ELEMENT

    一個(gè)元素的開始

    ATTRIBUTE

    一個(gè)元素屬性

    NAMESPACE

    一個(gè)命名空間聲明

    CHARACTERS

    字符可以是文本,或是一個(gè)空格

    COMMENT

    一個(gè)注釋

    SPACE

    可忽略的空格

    PROCESSING_INSTRUCTION

    處理指令

    DTD

    一個(gè) DTD

    ENTITY_REFERENCE

    一個(gè)實(shí)體參考

    CDATA

    Cdata 節(jié)

    END_ELEMENT

    結(jié)束元素

    END_DOCUMENT

    結(jié)束文檔

    ENTITY_DECLARATION

    一個(gè)實(shí)體聲明

    NOTATION_DECLARATION

    一個(gè)標(biāo)志聲明

    ?

    表格 1.XMLStreamReader 事件

    ?

    ?

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


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

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

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

    ?

    ?

    六、使用 XMLEventReader 進(jìn)行分析

    ?

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

    首先,導(dǎo)入 StAX 類:

    import javax.xml.stream.*;
    import javax.xml.stream.events.*;
    import javax.xml.stream.XMLInputFactory;
      接下來,創(chuàng)建一個(gè) XMLInputFactory ,由它獲得一個(gè) 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 對象以獲得下一個(gè)事件:

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

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

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

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


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

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

    ?

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

    FeedBack:
    # re: 在JDK 6.0中基于StAX分析XML數(shù)據(jù)
    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  回復(fù)  更多評論
      

    <2006年9月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    1234567

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    文章分類

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 日本黄网站动漫视频免费| 精品亚洲永久免费精品| 特色特黄a毛片高清免费观看| 午夜不卡AV免费| 日本免费久久久久久久网站| 91福利免费视频| 免费A级毛片无码免费视| 国产一区二区三区无码免费| 国产亚洲美女精品久久久| 亚洲视频在线一区| 亚洲日韩一区二区一无码| 九九全国免费视频| 伊人久久免费视频| 午夜视频在线观看免费完整版| 亚洲人成网站18禁止一区| 亚洲成人精品久久| 亚洲精品无码中文久久字幕| 一个人看的hd免费视频| 最近免费中文字幕高清大全| 日日夜夜精品免费视频| 亚洲日本乱码在线观看| 亚洲一区二区影视| 国产精品综合专区中文字幕免费播放 | 亚洲影视自拍揄拍愉拍| 国产亚洲福利一区二区免费看| 十八禁在线观看视频播放免费| 国色精品卡一卡2卡3卡4卡免费| 亚洲av日韩av欧v在线天堂| 久久久久久a亚洲欧洲AV| 亚洲人成网站18禁止| a级在线免费观看| 在线观看成人免费视频| 亚洲乱码无码永久不卡在线| 亚洲砖码砖专无区2023| 国产在线观看免费视频软件| 免费理论片51人人看电影| 久久精品国产亚洲香蕉| 成a人片亚洲日本久久| 67194国产精品免费观看| 亚洲成人高清在线| 亚洲va精品中文字幕|