AXIOM的全稱為AXIs Object Model,最初是作為Apache Axis 2的XML對象模型開發的。但是后來變成了WS Commons Project的一部分,以便收益于Axis2外的其他項目。 Overview and Features ????? AXIOM是一個實現了延遲構造和拉解析(pull parsing)的輕量級XML解析器。延遲構造是AXIOM的最重要的特性之一,它可以實現對象在使用時才構造。而這個延遲構造的功能實現是基于標準的拉式解析器——StAX。 What is Pull Parsing? ??? 簡單介紹一下“拉式解析”的概念。一個XML文檔可以通過“拉式”或“推式”中任意一種方式來解析?!袄健笔悄壳傲餍械腦ML解析方式。傳統的XML解 析框架,例如SAX和DOM都是“推式”的,那意味著解析過程是由解析器本身來控制的。這樣的實現方式看似不錯,并且使用方便,但是在解析大型XML文檔 時效率就差了,因為整個文檔對象模型都要生成在內存里。而“拉式解析”剛好顛倒了解析過程中的控制關系,解析器只對用戶指定的部分進行解析(好比傳送帶上 的一盤盤壽司,我只取我感興趣的那盤,而不是把經過我面前的都拿下來,篩選后再把不感興趣的放上去,留下想吃的那部分)。這樣用戶可以決定是保存或是拋棄 解析器生成的事件。OM(對象模型)便是基于“拉式解析”的。 Working with AXIOM 要使用AXIOM需要下載它的API包。AXIOM開始是作為AXIS2的一部分出現的,但現在已經可以單獨下載了,當然在AXIS2的發布包里還是可以找到它的。 Creating an AXIOM 我們可以通過三種方式創建一個AXIOM:Pull Event stream,Push Event stream或者由程序自動創建。本文主要演示通過第一種和第三種方式來構建一個AXIOM,它們也是創建AXIOM最常用的方式。 Creating an AXIOM from an Input Stream 下面的代碼演示了如何從一個文件輸入流來創建一個AXIOM:
注意,當我們從builder獲取到document element時,builder僅僅是返回一個指向,我們將要操作的XML數據仍然在數據流里,沒有被取出來,對象樹也沒有被創建。對象樹只有到我們導航或是構建AXIOM時創建。 Creating an AXIOM Using a String 現在,讓我們通過一個字符串來創建AXIOM,這是一個非常簡單、方便的方式。
String xmlString = "<book>" +
"<name>Quick-start Axis</name>" +
"<isbn>978-1-84719-286-8</isbn>" +
"</book>";
ByteArrayInputStream xmlStream = new ByteArrayInputStream(xmlString.
getBytes());
//create a builder. Since we want the XML as a plain XML, we can just use the plain OMBuilder
StAXBuilder builder = new StAXOMBuilder(xmlStream);
//return the root element.
OMElement documentElement = builder.getDocumentElement();
在上面的代碼里,我們可以看到一組factory.create*方法。這些方法可以用來創建不同的XML對象。在AXIOM里,推薦使用這樣的方法來創建AXIOM對象,因為這樣可以使得在AXIOM的其它不同實現中切換變得簡單。 Adding a Child Node and Attributes 到目前為止,我們已經學習了創建AXIOM和使用StAX的API,但這些對于使AXIOM工作起來還是不夠的。我們還需要學習向AXIOM添加子節點。 在OMElement 接口中已經定義了基本的添加和刪除方法:
public void addChild(OMNode omNode);
public void addAttribute(OMAttribute omAttribute);
? 下面讓我們實現向root元素添加子節點:
root.addChild(name);
root.addChild(isbn);
*add()方法總是將新添加的子節點作為最后一個子節點加入到父節點中。
?
Working with OM Namespaces 由于對命名空間的處理也是解析XML的關鍵部分,因此AXIOM也提供了一系列API來處理命名空間: public OMNamespace declareNamespace(String uri, String prefix); public OMNamespace declareNamespace(OMNamespace namespace); public OMNamespace findNamespace(String uri, String prefix) throws OMException; 以上方法對于使用其它解析方法處理過XML的朋友來說應該不難理解,但需要注意的是,一個已經添加過一次的命名空間聲明不能被再次添加。 findNamespace方法是一個非常便捷的方法用來在整個對象樹中找到一個命名空間對象。 在序列化過程中,一個由工廠方法直接創建的命名空間不會被立即聲明,只有當序列化到這個命名空間被使用的地方(即遇到它的前綴)時才會被聲明。 如果我們序列化我們創建的元素,我們會得到:
Traversing the AXIOM Tree 在前面的章節,我們已經學習了如何創建一個元素,如何添加子節點,如何創建命名空間和屬性。現在,就讓我們來遍歷一下整個AXIOM樹。 遍歷對象結構可以通過常用的獲取子節點列表的方法,但在AXIOM里,獲取子節點得到的是一個iterator。下面的代碼演示來如何通過給定的節點來訪問子節點。子節點的類型為OMNode,可以是OMText或OMElement中的任意一種。