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

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

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

    隨筆 - 3, 文章 - 152, 評論 - 17, 引用 - 0
    數據加載中……

    JAXP: Coding for Parser & Transformer Independence

    Author: Henry Chen                     譯者:李力
    介紹
    由于可擴展標記語言(XML)的易用性和輕攜性,其近年來獲得了極大的流行。它與Java結合起來,非常適用于可移植的數據和代碼。每一個與XML文檔打交道的Java程序員,無論是讀數據,還是進行數據轉換,都必須對Java API’s for XML Processing (JAXP)有一個很深的理解。編寫XML解析器無關的代碼有許多好處,JAXP API 是用于XML的,就像JDBC API是用于關系型數據庫的。這篇介紹性的文章幫助開發者學習JAXP API,并讓開發者對可插入層(pluggability layer)有一個很深的理解,這樣,開發者就可以在他們的應用程序中自如的更換解析器。
    JAXPack
       SUN推出了一個用于XML的Java API 和架構,稱其為Java XML Pack (JAXPack - http://java.sun.com/xml/javaxmlpack.html)。下載包中包括了現在行業中一些重要的標準。這篇文章中,我們將注意力放在JAXP(the API for XML Processing)上,Sybase的Easerver從版本3.6.1開始支持JAXP。
       首先,我們看一下JAXP提供的解析能力,解析XML文檔有兩種最基本的方法, 基于事件的SAX和遍歷樹的DOM。開發者可以選擇最適合他們需要的方法。讓我們鉆進去,深入的看一下這些API。
    這篇文章中,我們用圖1中的XML文檔來闡述我們的例子。


     
    SAX
    Simple API for XML Parsing (SAX)是事件驅動的,它從頭到尾遍歷整個文檔, 當它遇到一個語法結構時,它會通知運行它的程序,這些是通過事件處理接口ContentHandler, ErrorHandler, DTDHandler, 和 EntityResolver中的回調方法實現的。這些回調方法可以被開發者自定義實現來滿足一些特殊的要求。圖2描繪了SAX解析器解析文檔是各種組件之間的關系。
     

    我們將遍歷圖1中XML文檔,并且給出SAX解析器一行一行的解析是調用回調方法的細節,在這個例子中,我們不包括對ignorableWhiteSpace方法調用。


    現在你已經對SAX如何工作有一個總體的了解,接下來,讓我們看一看用真真的Java代碼實現的例子,我們實現的程序的完整代碼可以在http://www.sybase.com/developer.上找到,出于這篇文章的目的,我將只用一些代碼相關部分的片斷。

    1. public class SAXExample extends DefaultHandler {
    2. SAXParserFactory factory = SAXParserFactory.newInstance();
    3. SAXParser saxParser = factory.newSAXParser();
    4. DefaultHandler handler = new SAXExample();
    5. saxParser.parse( new File(argv[0]), handler)

     
      注意我們繼承了DefaultHandler Class, 這個類用一些空方法實現了ContentHandler, ErrorHandle, DTDHandler,和 EntityResolver接口,這樣,程序員就可以只覆蓋一些他們需要的方法。
    在我們解析之前,我們首先需要通過調用newInstance方法,實例化一個SAXParserFactory,這個方法用某個特定的查找順序來決定使用哪一個SAXParserFactory的實現,這就意味著,解析器更改時,代碼無需重新編譯。
    一旦我們實例化了一個SAXParserFactory,我們可以設置三個選項,這些決定了隨后如何產生SAXParser的對象。
    SAXParserFactory  使namespace可用
    SetValidating     打開驗證
    SetFeature         設定底層實現的特征
    SAXParserFactory配置好后,我們調用newSAXParser方法來實例化一個JAXP SAXParser對象,這個對象包裝了一個底層的SAX解析器,并且允許我們以廠商中立的方式與其交互,現在,我們就可以解析了。在這個例子中,我們用File對象作為輸入,它還可以接受其他的輸入源,如InputSource對象,InputStream 對象,或者Uniform Resource Identifier (URI)。
    注意程序是如何使自己成為解析器的處理者(handler)的,這意味著解析器將調用SAXExampl中的回調方法的,當解析方法一行一行的解析XML文件時,我們的處理類中的回調事件就發生了。

    DOM
    Document Object Model (DOM)是將XML文檔解析成樹狀對象的一套接口,每一個對象,或結點(node)都有一個用org.w3c.dom包中的接口表示的類型(type).如Element, Attribute,
    Comment, 和Text。可以像操作其他任何樹狀數據結構一樣來操作DOM樹狀對象,它允許隨機訪問XML文檔中特定部分的數據,并且修改它,這些是SAX解析器做不到的。
         這種方法的缺點是它非常占用內存和CPU資源,因為構建DOM樹時需要將整個XML文檔讀入并保持在內存中。
     

    讓我們看一個例子:
    1.     public class DOMExample {
    2. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    3. DocumentBuilder domParser = factory.newDocumentBuilder();
    4. Document document = domParser.parse( new File(argv[0]) );

    .
    與SAX類似,我們首先用newInstance方法實例化一個DocumentBuilderFactory對象,同樣類似SAXParserFactory,工廠可以配置用來處理namespace(命名空間)和validation(驗證)。另外,還有一些其他可選的設置,但這已經超出了本文的范圍。工廠對象準備好后,我們就可以創造一個DocumentBuilder對象,它可用來解析xml文件和創造Document對象,同樣類似SAXParser的parse方法,Document對象可以接受InputSource對象,InputStream對象,或者URI。

    1. Node thePhonebook = document.getDocumentElement();
    2. NodeList personList = thePhonebook.getChildNodes();
    3. Node currPerson = personList.item(0);
    4. Node fullName = currPerson.getChildNodes().item(0);
    5. Node firstName = fullName.getChildNodes().item(0);
    6. Node lastName = fullName.getChildNodes().item(1);
    7. Text firstNameText = (Text)firstName.getFirstChild();
    8. Text lastNameText = (Text)lastName.getFirstChild();
    9. Node phone = currPerson.getChildNodes().item(1);
    10. Node workPhone = phone.getChildNodes().item(0);
    11. Node homePhone = phone.getChildNodes().item(1);
    12. Text workPhoneText = (Text)workPhone.getFirstChild();
    13. Text homePhoneText = (Text)homePhone.getFirstChild();

    一旦我們擁有了Document DOM對象,我們就可以像操作其他樹一樣操作它。getDocumentElement方法返回根元素,從根元素可以得到子節點的NodeList,并且可以處理它們。在DOM樹結構的葉結點,我們可以找到Text對象,它繼承了Node。調用getData方法可以返回字符串的值。如你所見,使用者在操作數據時必須對文檔數據的結構有一個了解,而在SAX中,解析器僅僅對它遇到的數據反應。
    但是,DOM最大的優點是它可以對數據結構進行修改,例如:

    1. if (firstNameText.getData().equals("Richard") &&
    2. lastNameText.getData().equals("Mullins")) {
    3.     homePhoneText.setNodeValue("(510)333-3333");
    4. }

    用setNodeValue方法可以改變DOM樹中的數據,隨后,我們將看XSLT如何將一個新樹寫入一個數據文件。
    XSLT
    XSL轉換(XSLT)是將XML文檔轉換為其他XML文檔或其他格式的文檔(如HTML)的一組API,  XML樣式語言(XSL)在轉換中作用巨大,用其定義的樣式表包含了格式規則,指定了文檔如何顯示。

     
    這里有一個例子,將DOM對象轉換為XML文檔:
    1. //create a new DOMSource using the root node of an existing DOM tree
    2. DOMSource source = new DOMSource(thePhonebook);
    3. StreamResult result = new StreamResult(System.out);
    4. TransformerFactory tFactory = TransformerFactory.newInstance();
    5. Transformer transformer = tFactory.newTransformer();
    6. transformer.transform(source, result);

    我們首先用newInstance方法實例化一個TransformerFactory對象,它用特定的查找順序來決定使用哪一個轉換器實現。和SAX和DOM工廠一樣,可以對TransformerFactory對象進行一些配置,來影響Transformer對象的創建。用newTransformer方法創建好Transformer對象后,就可以調用transform方法,它將一個Source對象(DOMSource,SAXSource, StreamSource)轉換為Result對象(DOMResult, SAXResult, StreamResult)。
    抽象層
    前面已經提到過,用某種特定的查找順序來決定使用哪個SAX, DOM 和XSLT的實現,下面的API定義了查找順序:
     .使用javax.xml.parsers.SAXParserFactory(或javax.xml.parsers.DocumentBuilderFactory)系統屬性(system property)。
     .使用JRE目錄中“lib/jaxp.properties”屬性文件定義的javax.xml.parsers.SAXParserFactory屬性的值,這個值必須包括了實現類的全名。
     .使用Service API,它可以在運行系統中使用的JAR文件中包括的META-INF/services/javax.xml.parsers.SAXParserFactory文件中查找類名。
     .使用平臺默認的SAXParserFactory實例。
    使用DOM時,你只需將javax.xml.parsers.SAXParserFactory替換為javax.xml.parsers.DocumentBuilderFactory,類似,使用XSLT時,你用javax.xml.transform.TransformerFactory替換。
    總結
    如你所見,你寫的代碼只需與抽象層打交道。這保證了廠商的無關性,你可以快速和輕松的替換你的解析器的實現。解析XML文檔時,Java開發者可以根據他們的需要設置兩個選項。SAX是利用回調過程的事件驅動模型,而DOM是一種游歷樹的模型,它在操作數據前必須將XML文檔解析成樹,XSLT則可以將XML文檔轉換為另一種XML文檔或者其他格式,如HTML。總之,JAXP非常的強大,靈活,它提供的簡單可用的工具可以滿足大多數Java開發者處理XML文檔時的需要。

    posted on 2005-03-23 16:09 閱讀(210) 評論(0)  編輯  收藏 所屬分類: Java_Xml

    主站蜘蛛池模板: 黄色a级片免费看| 亚洲精品久久无码| 久久久久久国产a免费观看不卡| 免费看www视频| 欧美色欧美亚洲另类二区| 精品国产精品久久一区免费式| 久久夜色精品国产噜噜亚洲a| 国产h视频在线观看免费| 亚洲中文字幕久在线| 欧洲黑大粗无码免费| 亚洲精品无码久久久久APP | 亚洲另类图片另类电影| 无码人妻久久一区二区三区免费丨| 亚洲国产精品成人综合色在线婷婷| 91手机看片国产永久免费| 亚洲色偷偷色噜噜狠狠99| 免费无遮挡无码永久在线观看视频| 四虎精品成人免费视频| 伊人久久大香线蕉亚洲| 久久99精品免费视频| 久久亚洲精品专区蓝色区| 国产高清在线免费| 不卡视频免费在线观看| 亚洲国产精品免费在线观看| 成人啪精品视频免费网站| 永久免费精品影视网站| 亚洲精品线在线观看| 成人毛片18女人毛片免费视频未| 四虎影视在线看免费观看| 亚洲激情在线观看| 永久黄网站色视频免费| 中文字幕在线视频免费| 久久精品国产亚洲AV蜜臀色欲| 免费观看午夜在线欧差毛片| 伊人久久大香线蕉免费视频| 亚洲一区在线视频| 伊人久久大香线蕉亚洲五月天| 成人AV免费网址在线观看| 国产精品内射视频免费| 亚洲一区二区三区久久久久| 国产日产亚洲系列最新|