JDOM

JDOM是一種使用XML的獨特Java工具包,用於快速開發XML應用程式。它的設計包含Java語言的語法乃至語義。

說明

JDOM是兩位著名的 Java 開發人員兼作者,Brett Mclaughlin 和 Jason Hunter 的創作成果, 2000 年初在類似於 Apache 協定的許可下,JDOM 作為一個開放原始碼項目正式開始研發了。它已成長為包含來自廣泛的 Java 開發人員的投稿、集中反饋及錯誤修復的系統,並致力於建立一個完整的基於 Java 平台的解決方案,通過 Java 代碼來訪問、操作並輸出 XML 數據。
雖然許多Java 開發人員每天都在使用 XML,Sun 卻在將 XML 整合進 Java 平台方面落後了。因為在 XML 成為從商家對商家集成到 Web 站點內容流水化等方面的關鍵技術之前,Java 2 平台就已經非常流行了。Sun 已經使用 JSR 過程使之成為現存 XML API 的鼻祖,這一點已被廣泛接受。目前最顯著的是加入了 JAXP (用於 XML 語法分析的 Java API),其中包含了三個軟體包
·org.w3c.dom ,W3C 推薦的用於 XML 標準規劃文檔對象模型的 Java 工具
·org.xml.sax ,用於對 XML 進行語法分析的事件驅動的簡單 API
·javax.xml.parsers ,工廠化工具,允許應用程式開發人員獲得並配置特殊的語法分析器工具 JDOM 能夠替換 org.w3c.dom 軟體包來有計畫地操作 XML 文檔
JDOM是一個開源項目,它基於樹型結構,利用純JAVA的技術對XML文檔實現解析、生成、序列化以及多種操作。
JDOM 直接為JAVA編程服務。它利用更為強有力的JAVA語言的諸多特性(方法重載、集合概念以及映射),把SAX和DOM的功能有效地結合起來。
Jdom是用Java語言讀、寫、操作XML的新API函式。Jason Hunter 和 Brett McLaughlin公開發布了它的1.0版本。在直覺、簡單和高效的前提下,這些API函式被最大限度的最佳化。在接下來的篇幅里將介紹怎么用Jdom去讀寫一個已經存在的XML文檔。
在使用設計上儘可能地隱藏原來使用XML過程中的複雜性。利用JDOM處理XML文檔將是一件輕鬆、簡單的事。
JDOM 在2000年的春天被Brett McLaughlin和Jason Hunter開發出來,以彌補DOM及SAX在實際套用當中的不足之處。
這些不足之處主要在於SAX沒有文檔修改、隨機訪問以及輸出的功能,而對於DOM來說,JAVA程式設計師在使用時來用起來總覺得不太方便。
DOM的缺點主要是來自於由於Dom是一個接口定義語言(IDL),它的任務是在不同語言實現中的一個最低的通用標準,並不是為JAVA特別設計的。JDOM的最新版本為JDOM Beta 9。最近JDOM被收錄到JSR-102內,這標誌著JDOM成為了JAVA平台組成的一部分。
在 JDOM 中,XML 元素就是 Element 的實例,XML 屬性就是 Attribute 的實例,XML 文檔本身就是 Document 的實例。
因為 JDOM 對象就是像 Document、Element 和 Attribute 這些類的直接實例,因此創建一個新 JDOM 對象就如在 Java 語言中使用 new 操作符一樣容易。JDOM 的使用是直截了當的。
JDOM 使用標準的 Java 編碼模式。只要有可能,它使用 Java new 操作符而不故弄玄虛使用複雜的工廠化模式,使對象操作即便對於初學用戶也很方便。

JDOM包概覽

JDOM是由以下幾個包組成的
org.jdom包含了所有的xml文檔要素的java類
org.jdom.adapters包含了與dom適配的java類
org.jdom.filter包含了xml文檔的過濾器類
org.jdom.input包含了讀取xml文檔的類
org.jdom.output包含了寫入xml文檔的類
org.jdom.transform包含了將jdomxml文檔接口轉換為其他xml文檔接口
org.jdom.xpath包含了對xml文檔xpath操作的類

JDOM類說明

1、org.JDOM這個包里的類是你解析xml檔案後所要用到的所有數據類型。
Attribute
CDATA
Coment
DocType
Document
Element
EntityRef
Namespace
ProscessingInstruction
Text
2、org.JDOM.transform在涉及xslt格式轉換時應使用下面的2個類
JDOMSource
JDOMResult
org.JDOM.input
3、輸入類,一般用於文檔的創建工作
SAXBuilder
DOMBuilder
ResultSetBuilder
4、org.JDOM.output輸出類,用於文檔轉換輸出
XMLOutputter
SAXOutputter
DomOutputter
JTreeOutputter
使用前注意事項:
1.JDOM對於JAXP以及TRax的支持
JDOM支持JAXP1.1:你可以在程式中使用任何的parser工具類,默認情況下是JAXP的parser。
制定特別的parser可用如下形式
SAXBuilderparser
=newSAXBuilder("org.apache.crimson.parser.XMLReaderImpl");
Documentdoc=parser.build("http://www.cafeconleche .org/");
//workwiththedocument...
JDOM也支持TRaX:XSLT可通過JDOMSource以及JDOMResult類來轉換(參見以後章節)
2.注意在JDOM里文檔(Document)類由org.JDOM.Document來表示。這要與org.w3c.dom中的Document區別開,這2種格式如何轉換在後面會說明。
以下如無特指均指JDOM里的Document。

JDOM主要使用方法

1.Document類

(1)Document的操作方法:
Element root=new Element("GREETING");
Document doc=new Document(root);
root.setText("HelloJDOM!");
或者簡單的使用Document doc=new Document(new Element("GREETING").setText("HelloJDOM!t"));
這點和DOM不同。Dom則需要更為複雜的代碼,如下:
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Documentdoc=builder.newDocument();
Element root=doc.createElement("root");
Text text=doc.createText("Thisistheroot");
root.appendchild(text);
doc.appendChild(root);
注意事項:JDOM不允許同一個節點同時被2個或多個文檔相關聯,要在第2個文檔中使用原來老文檔中的節點的話。首先需要使用detach()把這個節點分開來。
(2)從檔案、流、系統ID、URL得到Document對象:
DOMBuilder builder=new DOMBuilder();
Document doc=builder.build(newFile("jdom_test.xml"));
SAXBuilder builder=new SAXBuilder();
Document doc=builder.build(url);
在新版本中DOMBuilder已經Deprecated掉DOMBuilder.builder(url),用SAX效率會比較快。
這裡舉一個小例子,為了簡單起見,使用String對象直接作為xml數據源:
Public jdom Test(){
String textXml=null;
textXml="";
textXml=textXml+ "aaabbbcccddd";
textXml=textXml+"";
SAXBuilder builder=new SAXBuilder();
Document doc=null;
Reader in=new StringReader(textXml);
try {
doc=builder.build(in);
Element root=doc.getRootElement();
List ls=root.getChildren();//注意此處取出的是root節點下面的一層的Element集合
for ( Iterator iter=ls.iterator(); iter.hasNext(); ){
Element el=(Element)iter.next();
if (el.getName().equals("to")){
System.out.println(el.gettext());
}
}
} catch(IOException ex) {
ex.printStackTrace();
} catch(JDOMException ex) {
ex.printStackTrace();
}
}
(3)DOM的document和JDOM的Document之間的相互轉換使用方法,簡單!
DOMBuilder builder=new DOMBuilder();
org.jdom.Document jDomDocument=builder.build(domDocument);
DOMOutputter converter=newDOMOutputter();//workwiththeJDOMdocument…
org.w3c.dom.Document domDocument=converter.output(jdomDocument);
//workwiththeDOMdocument…

2.XML文檔輸出

XMLOutPutter類:
JDOM的輸出非常靈活,支持很多種io格式以及風格的輸出
Document doc=newDocument(...);
XMLOutputter outp=newXMLOutputter();
outp.output(doc,fileOutputStream);//Rawoutput
outp.setTextTrim(true);//Compressedoutput
outp.output(doc,socket.getOutputStream());
outp.setIndent("");//Prettyoutput
outp.setNewlines(true);
outp.output(doc,System.out);
詳細請參閱最新的JDOMAPI手冊

3.Element類


(1)瀏覽Element樹
Element root=doc.getRootElement();//獲得根元素element
List allChildren=root.getChildren();//獲得所有子元素的一個list
List namedChildren=root.getChildren("name");//獲得指定名稱子元素的list
Element child=root.getChild("name");//獲得指定名稱的第一個子元素
JDOM給了我們很多很靈活的使用方法來管理子元素(這裡的List是java.util.List)
List allChildren=root.getChildren();
allChildren.remove(3);//刪除第四個子元素
allChildren.removeAll(root.getChildren("jack"));//刪除叫“jack”的子元素
root.removeChildren("jack");//便捷寫法
allChildren.add(new Element("jane"));//加入
root.addContent(new Element("jane"));//便捷寫法
allChildren.add(0,new Element("first"));
(2)移動Elements:
在JDOM里很簡單
Element movable=new Element("movable");
parent1.addContent(movable);//place
parent1.removeContent(movable);//remove
parent2.addContent(movable);//add
在Dom里
Element movable=doc1.createElement("movable");
parent1.appendChild(movable);//place
parent1.removeChild(movable);//remove
parent2.appendChild(movable);//出錯!

補充:糾錯性

JDOM的Element構造函式(以及它的其他函式)會檢查element是否合法。
而它的add/remove方法會檢查樹結構,檢查內容如下:
1.在任何樹中是否有迴環節點
2.是否只有一個根節點
3.是否有一致的命名空間(Namespaces)
(3)Element的text內容讀取
Acooldemo
//Thetextisdirectlyavailable
//Returns"\nAcooldemo\n"
String desc=element.getText();
//There'saconvenientshortcut
//Returns"Acooldemo"
String desc=element.getTextTrim();
(4)Elment內容修改
element.setText("Anewdescription");
3.可正確解釋特殊字元
element.setText("

JDOM的套用

(一)、XML文檔創建
我們由零開始利用JDOM生成一個XML文檔。最後的結果(樣本文檔)看起來象這樣:
kingwong
87654321

1.以 Myinfo 創建文檔

Element rootElement = new Element("MyInfo");//所有的XML元素都是 Element 的實例。根元素也不例外:)
Document myDocument = new Document(rootElement);//以根元素作為參數創建Document對象。一個Document只有一個根,即root元素。

2.給根元素添加屬性

Attribute rootAttri = new Attribute("comment","introduce myself");//創建名為 commnet,值為 introduce myself 的屬性。
rootElement.setAttribute(rootAttri);//將剛創建的屬性添加到根元素。
這兩行代碼你也可以合成一行來寫,象這樣:
rootElement.setAttribute(new Attribute("comment","introduce myself"));
或者
rootElement.setAttribute("comment","introduce myself");

3.添加元素和子元素

JDOM里子元素是作為 content(內容)添加到父元素裡面去的,所謂content就是類似上面樣本文檔中之間的東東,即kingwong。囉嗦了點是吧:)
Element nameElement = new Element("name");//創建 name 元素
nameElement.addContent("kingwong");//將kingwong作為content添加到name元素
rootElement.addContent(nameElement);//將name元素作為content添加到根元素
這三行你也可以合為一句,象這樣:
rootElement.addContent((Content)(new Element("name").addContent("kingwong")));//因為addContent(Content child)方法返回的是一個Parent接口,而Element類同時繼承了Content類和實現了Parent接口,所以我們把它造型成Content。
我們用同樣的方法添加帶屬性的子元素
rootElement.addContent(new Element("sex").setAttribute("value","male"));//注意這裡不需要轉型,因為addAttribute(String name,String value)返回值就是一個 Element。
同樣的,我們添加元素到根元素下,用法上一樣,只是稍微複雜了一些:
rootElement.addContent((Content)(new Element("contact").addContent((Content)(new Element("telephone").addContent("87654321")))));
如果你對這種簡寫形式還不太習慣,你完全可以分步來做,就象本節剛開始的時候一樣。事實上如果層次比較多,寫成分步的形式更清晰些,也不容易出錯。

4.刪除子元素

這個操作比較簡單:
rootElement.removeChild("sex");//該方法返回一個布爾值
到目前為止,我們學習了一下JDOM文檔生成操作。上面建立了一個樣本文檔,可是我們怎么知道對不對呢?因此需要輸出來看一下。我們將JDOM生成的文檔輸出到控制台,使用 JDOM 的 XMLOutputter 類。

5. JDOM 轉為 XML 文本

XMLOutputter xmlOut = new XMLOutputter(" ",true);
try {
xmlOut.output(myDocument,System.out);
} catch (IOException e) {
e.printStackTrace();
}
XMLOutputter 有幾個格式選項。這裡我們已指定希望子元素從父元素縮進兩個空格,並且希望元素間有空行。
new XMLOutputter(java.lang.String indent, boolean newlines)這個方法在最新版本中已經不建議使用。JDOM有一個專門的用來定義格式化輸出的類:org.jdom.output.Format,如果你沒有特殊的要求,有時候使用裡面的幾個靜態方法(應該可以說是預定義格式)如 getPrettyFormat()就可以了。我們把上面的輸出格式稍微改一下,就象這樣:
XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
6.將JDOM文檔轉化為其他形式
XMLOutputter 還可輸出到 Writer 或 OutputStream。為了輸出JDOM文檔到一個文本檔案,我們可以這樣做:
FileWriter writer = new FileWriter("/some/directory/myFile.xml");
outputter.output(myDocument, writer);
writer.close();
XMLOutputter 還可輸出到字元串,以便程式後面進行再處理:
Strng outString = xmlOut.outputString(myDocument);
當然,在輸出的時候你不一定要輸出所有的整個文檔,你可以選擇元素進行輸出:
xmlOut.output(rootElement.getChild("name"),System.out);
一句話,JDOM非常靈活方便!如果你想進一步研究JDOM,請到官方網站去看一看:http://www.jdom .org
本節示例源碼:
package com.cyberobject.study;
import java .io.IOException;
import org.jdom.Attribute;
import org.jdom.Content;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
/**
* @author kingwong
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class TestJDOM {
public static void main(String[] args)
{
Element rootElement = new Element("MyInfo");
Document myDocument = new Document(rootElement);
// Attribute rootAttri = new Attribute("comment","introduce myself");
// rootElement.setAttribute(rootAttri);
rootElement.setAttribute("comment","introduce myself");
//rootElement.setAttribute(new Attribute("comment","introduce myself"));
// Element sexElement = new Element("sex");
// rootElement.addContent(sexElement);
// Element nameElement = new Element("name");
// nameElement.addContent("kingwong");
// rootElement.addContent(nameElement);
rootElement.addContent((Content)(new Element("name").addContent("kingwong")));
rootElement.addContent(new Element("sex").setAttribute("value","male"));
rootElement.addContent((Content)(new Element("contract").addContent((Content)(new Element("telephone").addContent("87654321")))));
rootElement.removeChild("sex");
XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
try {
xmlOut.output(myDocument,System.out);
//xmlOut.output(rootElement.getChild("name"),System.out);
//String outString = xmlOut.outputString(myDocument);
} catch (IOException e) {
e.printStackTrace();
}
}
}

XML文檔解析

JDOM 不光可以很方便的建立XML文檔,它的另一個用處是它能夠讀取並操作現有的 XML 數據。
JDOM的解析器在org.jdom.input.*這個包里,其中的DOMBuilder的功能是將DOM模型的Document解析成JDOM模型的Document;SAXBuilder的功能是從檔案或流中解析出符合JDOM模型的XML樹。由於我們經常要從一個檔案里讀取數據,因此我們應該採用後者作為解析工具。
解析一個xml文檔,基本可以看成以下幾個步驟:
1.實例化一個合適的解析器對象
本例中我們使用SAXBuilder:
SAXBuilder sb = new SAXBuilder();
2.以包含XML數據的檔案為參數,構建一個文檔對象myDocument
Document myDocument = sb.build(/some/directory/myFile.xml);
3.獲到根元素
Element rootElement = myDocument.getRootElement();
一旦你獲取了根元素,你就可以很方便地對它下面的子元素進行操作了,下面對Element對象的一些常用方法作一下簡單說明:
getChild("childname") 返回指定名字的子節點,如果同一級有多個同名子節點,則只返回第一個;如果沒有返回null值。
getChildren("childname") 返回指定名字的子節點List集合。這樣你就可以遍歷所有的同一級同名子節點。
getAttributeValue("name") 返回指定屬性名字的值。如果沒有該屬性則返回null,有該屬性但是值為空,則返回空字元串
getChildText("childname") 返回指定子節點的內容文本值。
getText() 返回該元素的內容文本值。
還有其他沒有羅列出來的方法,如果需要的話,可以隨時查閱JDOM的線上文檔:http://www.jdom.org/docs/apidocs/index.html。當然你可以在你需要的地方添加、刪除元素操作,還記得上面的創建XML的方法嗎?呵呵~~~
學習新東東還是從實例學起最為快捷,下面簡單舉個例子,就以上面的XML樣本代碼來學習JDOM的XML解析。本例中讀取了樣本XML檔案里一些屬性和content,最後我們還在contact元素里插入了一個新元素[email protected]" />。儘管我們實現了對於XML的基本操作,細心的朋友可能會
有疑問:如果XML文檔的層次稍微複雜一些,如果嵌套多達幾十上百層的話(開個玩笑),如果靠這樣從根元素一級一級地通過getChild("childname")來訪問子元素的話,將會非常痛苦!是的,的確是這樣,但是我們有另一個有力的工具XPath,為什麼不用呢?這是後話!先賣個關子(手敲累啦,下回吧,呵呵)。
/*
* Created on 2004-8-21
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package com.cyberobject.study;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
/**
* @author kingwong
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class TestJDOM2 {
public static void main(String[] args){
SAXBuilder sb = new SAXBuilder();
try
{
Document doc = sb.build("myFile.xml");
Element root = doc.getRootElement();
String str1 = root.getAttributeValue("comment");
System.out.println("Root Element's comment attribute is : " + str1);
String str2 = root.getChild("sex").getAttributeValue("value");
System.out.println("sex Element's value attribute is : " + str2);
String str3 = root.getChildText("name");
System.out.println("name Element's content is :" + str3);
String str4 = root.getChild("contact").getChildText("telephone");
System.out.println("contact Element's telephone subelement content is : " + str4 + "\n");
Element inputElement = root.getChild("contact");
inputElement.addContent(new Element("email").setAttribute("value","wanghua @cyberobject .com"));
XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
String outStr = xmlOut.outputString(root);
System.out.println(outStr);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

相關詞條

相關搜尋

熱門詞條

聯絡我們