?一、JDOM簡(jiǎn)介
JDOM是一個(gè)開源項(xiàng)目,它基于樹型結(jié)構(gòu),利用純JAVA的技術(shù)對(duì)XML文檔實(shí)現(xiàn)解析、生成、序列化以及多種操作。
JDOM直接為JAVA編程服務(wù)。它利用更為強(qiáng)有力的JAVA語(yǔ)言的諸多特性(方法重載、集合概念以及映射),把SAX和DOM的功能有效地結(jié)合起來(lái)。
在使用設(shè)計(jì)上盡可能地隱藏原來(lái)使用XML過程中的復(fù)雜性。利用JDOM處理XML文檔將是一件輕松、簡(jiǎn)單的事。
JDOM在2000年的春天被BrettMcLaughlin和JasonHunter開發(fā)出來(lái),以彌補(bǔ)DOM及SAX在實(shí)際應(yīng)用當(dāng)中的不足之處。
這些不足之處主要在于SAX沒有文檔修改、隨機(jī)訪問以及輸出的功能,而對(duì)于DOM來(lái)說(shuō),JAVA程序員在使用時(shí)來(lái)用起來(lái)總覺得不太方便。
DOM的缺點(diǎn)主要是來(lái)自于由于Dom是一個(gè)接口定義語(yǔ)言(IDL),它的任務(wù)是在不同語(yǔ)言實(shí)現(xiàn)中的一個(gè)最低的通用標(biāo)準(zhǔn),并不是為JAVA特別設(shè)計(jì)的。JDOM的最新版本為JDOMBeta9。最近JDOM被收錄到JSR-102內(nèi),這標(biāo)志著JDOM成為了JAVA平臺(tái)組成的一部分。
二、JDOM包概覽
JDOM是由以下幾個(gè)包組成的
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文檔接口轉(zhuǎn)換為其他xml文檔接口
?
org.jdom.xpath???????????包含了對(duì)xml文檔xpath操作的類
三、JDOM類說(shuō)明
1、org.JDOM這個(gè)包里的類是你J解析xml文件后所要用到的所有數(shù)據(jù)類型。
Attribute
CDATA
Coment
DocType
Document
Element
EntityRef
Namespace
ProscessingInstruction
Text
2、org.JDOM.transform在涉及xslt格式轉(zhuǎn)換時(shí)應(yīng)使用下面的2個(gè)類
JDOMSource
JDOMResult
org.JDOM.input
3、輸入類,一般用于文檔的創(chuàng)建工作
SAXBuilder
DOMBuilder
ResultSetBuilder
4、org.JDOM.output輸出類,用于文檔轉(zhuǎn)換輸出
XMLOutputter
SAXOutputter
DomOutputter
JTreeOutputter
使用前注意事項(xiàng):
1.JDOM對(duì)于JAXP以及TRax的支持
JDOM支持JAXP1.1:你可以在程序中使用任何的parser工具類,默認(rèn)情況下是JAXP的parser。
制定特別的parser可用如下形式
SAXBuilder?parser
?=new?SAXBuilder("org.apache.crimson.parser.XMLReaderImpl");
?Document?doc=parser.build("http://www.cafeconleche.org/");
?//work?with?the?document...
JDOM也支持TRaX:XSLT可通過JDOMSource以及JDOMResult類來(lái)轉(zhuǎn)換(參見以后章節(jié))
2.注意在JDOM里文檔(Document)類由org.JDOM.Document來(lái)表示。這要與org.w3c.dom中的Document區(qū)別開,這2種格式如何轉(zhuǎn)換在后面會(huì)說(shuō)明。
以下如無(wú)特指均指JDOM里的Document。
四、JDOM主要使用方法
1.Ducument類
(1)Document的操作方法:
Element?root=new?Element("GREETING");
Document?doc=new?Document(root);
root.setText("Hello?JDOM!");
或者簡(jiǎn)單的使用Document?doc=new?Document(new?Element("GREETING").setText("HelloJDOM!t"));
這點(diǎn)和DOM不同。Dom則需要更為復(fù)雜的代碼,如下:
DocumentBuilderFactory?factory=DocumentBuilderFactory.newInstance();
DocumentBuilder?builder=factory.newDocumentBuilder();
Document?doc=builder.newDocument();
Element?root=doc.createElement("root");
Text?text=doc.createText("This?is?the?root");
root.appendChild(text);
doc.appendChild(root);
注意事項(xiàng):JDOM不允許同一個(gè)節(jié)點(diǎn)同時(shí)被2個(gè)或多個(gè)文檔相關(guān)聯(lián),要在第2個(gè)文檔中使用原來(lái)老文檔中的節(jié)點(diǎn)的話。首先需要使用detach()把這個(gè)節(jié)點(diǎn)分開來(lái)。
(2)從文件、流、系統(tǒng)ID、URL得到Document對(duì)象:
DOMBuilder?builder=new?DOMBuilder();
Document?doc=builder.build(new?File("jdom_test.xml"));
SAXBuilder?builder=new?SAXBuilder();
Document?doc=builder.build(url);
在新版本中DOMBuilder已經(jīng)Deprecated掉DOMBuilder.builder(url),用SAX效率會(huì)比較快。
這里舉一個(gè)小例子,為了簡(jiǎn)單起見,使用String對(duì)象直接作為xml數(shù)據(jù)源:
?Public?jdomTest(){
???String?textXml=null;
???textXml="<note>";
???textXml=textXml+
???????"<to>aaa</to><from>bbb</from><heading>ccc</heading><body>ddd</body>";
???textXml=textXml+"</note>";
???SAXBuilderbuilder=newSAXBuilder();
???Document?doc=null;
???Reader?in=new?StringReader(textXml);
???try{
?????doc=builder.build(in);
?????Element?root=doc.getRootElement();
?????List?ls=root.getChildren();//注意此處取出的是root節(jié)點(diǎn)下面的一層的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之間的相互轉(zhuǎn)換使用方法,簡(jiǎn)單!
DOMBuilder?builder=new?DOMBuilder();
org.jdom.Document?jdomDocument=builder.build(domDocument);
DOMOutputter?converter=new?DOMOutputter();//workwiththeJDOMdocument…
org.w3c.dom.Document?domDocument=converter.output(jdomDocument);
//workwiththeDOMdocument…
2.XML文檔輸出
XMLOutPutter類:
JDOM的輸出非常靈活,支持很多種io格式以及風(fēng)格的輸出
Document?doc=newDocument(...);
XMLOutputter?outp=new?XMLOutputter();
outp.output(doc,fileOutputStream);//Rawoutput
outp.setTextTrim(true);//Compressed?output
outp.output(doc,socket.getOutputStream());
outp.setIndent("");//Pretty?output
outp.setNewlines(true);
outp.output(doc,System.out);
詳細(xì)請(qǐng)參閱最新的JDOMAPI手冊(cè)
3.Element類:
(1)瀏覽Element樹
Element?root=doc.getRootElement();//獲得根元素element
List?allChildren=root.getChildren();//獲得所有子元素的一個(gè)list
List?namedChildren=root.getChildren("name");//獲得指定名稱子元素的list
Element?child=root.getChild("name");//獲得指定名稱的第一個(gè)子元素
JDOM給了我們很多很靈活的使用方法來(lái)管理子元素(這里的List是java.util.List)
List?allChildren=root.getChildren();
allChildren.remove(3);//刪除第四個(gè)子元素
allChildren.removeAll(root.getChildren("jack"));//刪除叫“jack”的子元素
root.removeChildren("jack");//便捷寫法
allChildren.add(newElement("jane"));//加入
root.addContent(newElement("jane"));//便捷寫法
allChildren.add(0,newElement("first"));
(2)移動(dòng)Elements:
在JDOM里很簡(jiǎn)單
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);//出錯(cuò)!
補(bǔ)充:糾錯(cuò)性
JDOM的Element構(gòu)造函數(shù)(以及它的其他函數(shù))會(huì)檢查element是否合法。
而它的add/remove方法會(huì)檢查樹結(jié)構(gòu),檢查內(nèi)容如下:
1.在任何樹中是否有回環(huán)節(jié)點(diǎn)
2.是否只有一個(gè)根節(jié)點(diǎn)
3.是否有一致的命名空間(Namespaces)
(3)Element的text內(nèi)容讀取
<description>
A?cool?demo
</description>
//The?text?is?directly?available
//Returns"\n?A?cool?demo\n"
String?desc=element.getText();
//There's?a?convenient?short?cut
//Returns?"A?cool?demo"
String?desc=element.getTextTrim();
(4)Elment內(nèi)容修改
element.setText("Anewdescription");
3.可正確解釋特殊字符
element.setText("<xml>content");
4.CDATA的數(shù)據(jù)寫入、讀出
element.addContent(newCDATA("<xml>content"));
String?noDifference=element.getText();
混合內(nèi)容
element可能包含很多種內(nèi)容,比如說(shuō)
<table>
<!?Some?comment-->
Some?text
<tr>Some?child?element</tr>
</table>
取table的子元素tr
String?text=table.getTextTrim();
Element?tr=table.getChild("tr");
也可使用另外一個(gè)比較簡(jiǎn)單的方法
List?mixedCo=table.getContent();
Iterator?itr=mixedCo.iterator();
while(itr.hasNext()){
Objecto=i.next();
if(o?instanceof?Comment){...}
//這里可以寫成Comment,Element,Text,CDATA,ProcessingInstruction,或者是EntityRef的類型
}
//現(xiàn)在移除Comment,注意這里游標(biāo)應(yīng)為1。這是由于回車鍵也被解析成Text類的緣故,所以Comment項(xiàng)應(yīng)為1。
mixedCo.remove(1);
4.Attribute類
<table?width="100%"?border="0"></table>
String?width=table.getAttributeValue("width");//獲得attribute
Int?border=table.getAttribute("border").getIntValue();
table.setAttribute("vspace","0");//設(shè)置attribute
table.removeAttribute("vspace");//刪除一個(gè)或全部attribute
table.getAttributes().clear();
5.處理指令(ProcessingInstructions)操作
一個(gè)Pls的例子
<?br?>
<?cocoon-processtype="xslt"?>
?????????|???????|
?????????|???????|
???????目標(biāo)????數(shù)據(jù)
處理目標(biāo)名稱(Target)
String?target=pi.getTarget();
獲得所有數(shù)據(jù)(data),在目標(biāo)(target)以后的所有數(shù)據(jù)都會(huì)被返回。
String?data=pi.getData();
String?type=pi.getValue("type");獲得指定屬性的數(shù)據(jù)
List?ls=pi.getNames();獲得所有屬性的名稱
6.命名空間操作
<xhtml:html
?xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xhtml:title>HomePage</xhtml:title>
</xhtml:html>
Namespace?xhtml=Namespace.getNamespace("xhtml","http://www.w3.org/1999/xhtml");
List?kids=html.getChildren("title",xhtml);
Element?kid=html.getChild("title",xhtml);
kid.addContent(newElement("table",xhtml));
7.XSLT格式轉(zhuǎn)換
使用以下函數(shù)可對(duì)XSLT轉(zhuǎn)換
最后如果你需要使用w3c的Document則需要轉(zhuǎn)換一下。
Public?static?Document?transform(String?stylesheet,Document?in)
???????????????????????????????????????Throws?JDOMException{
????try{
??????Transformer?transformer=TransformerFactory.newInstance()
????????????????????????????.new?Transformer(newstreamSource(stylesheet));
??????JDOMResult?out=new?JDOMResult();
??????transformer.transform(newJDOMSource(in),out);
??????return?out.getDocument();
????}
????catch(TransformerException?e){
??????throw?newJDOMException("XSLT?Trandformation?failed",e);
????}
??}
五、用例:
1、生成xml文檔:
?
?
Public?class?WriteXML{
???Public?void?BuildXML()?throws?Exception{
???????Element?root,student,number,name,age;????????
???????root=new?Element("student-info");//生成根元素:student-info
???????student=new?Element("student");//生成元素:student(number,name,age)????????????????????????????
???????number=new?Element("number");
???????name=new?Element("name");
???????age=new?Element("age");
???????Document?doc=new?Document(root);//將根元素植入文檔doc中
???????number.setText("001");
???????name.setText("lnman");
???????age.setText("24");
???????student.addContent(number);
???????student.addContent(name);
???????student.addContent(age);
???????root.addContent(student);
???????Format?format=Format.getCompactFormat();
???????format.setEncoding("gb2312");//設(shè)置xml文件的字符為gb2312
???????format.setIndent("???");//設(shè)置xml文件的縮進(jìn)為4個(gè)空格
???????XMLOutputterXML?Out=new?XMLOutputter(format);//元素后換行一層元素縮四格
???????XMLOut.output(doc,new?FileOutputStream("studentinfo.xml"));?
}
???Public?static?void?main(String[]?args)?throws?Exception{
???????WriteXML?w=new?WriteXML();
???????System.out.println("NowwebuildanXMLdocument.....");
???????w.BuildXML();
???????System.out.println("finished!");
}
}
生成的xml文檔為:
<?xmlversion="1.0"encoding="gb2312"?>
<student-info>
???<student>
???????<number>001</number>
???????<name>lnman</name>
???????<age>24</age>
???</student>
</student-info>
?
?
創(chuàng)建XML文檔2:
?Public?class?CreateXML{
?Public?void?Create(){
??try{
???Document?doc=new?Document();??
???ProcessingInstruction?pi=new?ProcessingInstruction("xml-stylesheet","type="text/xsl"href="test.xsl"");
???doc.addContent(pi);???
???Namespace?ns=Namespace.getNamespace("http://www.bromon.org");
???Namespace?ns2=Namespace.getNamespace("other","http://www.w3c.org");
???Element?root=new?Element("根元素",ns);
???root.addNamespaceDeclaration(ns2);
???doc.setRootElement(root);
???Elemente?l1=new?Element("元素一");
???el1.setAttribute("屬性","屬性一");???
???Text?text1=new?Text("元素值");
????????????Element?em=new?Element("元素二").addContent("第二個(gè)元素");
???el1.addContent(text1);
????????????el1.addContent(em);????????????
????????????Elementel2=newElement("元素三").addContent("第三個(gè)元素");
????????????root.addContent(el1);
????????????root.addContent(el2);????????????
????????????//縮進(jìn)四個(gè)空格,自動(dòng)換行,gb2312編碼
????????????XMLOutputter?outputter=new?XMLOutputter("?",true,"GB2312");
????????????outputter.output(doc,newFileWriter("test.xml"));
????????}catch(Exceptione)?{
?????????System.out.println(e);
????????}
????}????
????Public?static?void?main(String?args[]){
?????New?CreateXML().Create();
????}????
?}
2、讀取xml文檔的例子:
importorg.jdom.output.*;
importorg.jdom.input.*;
importorg.jdom.*;
importjava.io.*;
importjava.util.*;
public?class?ReadXML{
???public?static?void?main(String[]?args)?throws?Exception{
???????SAXBuilder?builder=new?SAXBuilder();
???????Document?read_doc=builder.build("studentinfo.xml");
???????Element?stu=read_doc.getRootElement();
???????List?list=stu.getChildren("student");
???????for(int?i=0;i<list.size();i++){
???????????Element?e=(Element)list.get(i);
???????????String?str_number=e.getChildText("number");
???????????String?str_name=e.getChildText("name");
???????????String?str_age=e.getChildText("age");
???????????System.out.println("---------STUDENT--------------");
???????????System.out.println("NUMBER:"+str_number);
???????????System.out.println("NAME:"+str_name);
???????????System.out.println("AGE:"+str_age);
???????????System.out.println("------------------------------");
???????????System.out.println();
???????}?
??????}
}
3、DTD驗(yàn)證的:
?Public?class?XMLWithDTD{
?Public?void?validate()?{
??try{
???SAXBuilder?builder=new?SAXBuilder(true);
???builder.setFeature("http://xml.org/sax/features/validation";,true);
???Document?doc=builder.build(newFileReader("author.xml"));???
???System.out.println("搞掂");
???XMLOutputter?outputter=new?XMLOutputter();
???outputter.output(doc,System.out);
??}catch(Exceptione){
???System.out.println(e);
??}??
?}
?Public?static?void?main(String?args[]){
??new?XMLWithDTD().validate();
?}?
?}
?需要說(shuō)明的是,這個(gè)程序沒有指明使用哪個(gè)DTD文件。DTD文件的位置是在XML中指定的,而且DTD不支持命名空間,一個(gè)XML只能引用一個(gè)DTD,所以程序直接讀取XML中指定的DTD,程序本身不用指定。不過這樣一來(lái),好象就只能使用外部式的DTD引用方式了?高人指點(diǎn)。
?
?
4、XMLSchema驗(yàn)證的:
?Public?classXMLWithSchema{
?String?xml="test.xml";
?String?schema="test-schema.xml";
?Public?void?validate(){
??try{
???SAXBuilder?builder=new?SAXBuilder(true);
???//指定約束方式為XMLschema
???builder.setFeature("http://apache.org/xml/features/validation/schema";,?true);
???//導(dǎo)入schema文件
builder.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation";,schema);
???Document?doc=builder.build(new?FileReader(xml));???
???System.out.println("搞掂");
???XMLOutputter?outputter=new?XMLOutputter();
???outputter.output(doc,System.out);
??}catch(Exceptione){
???System.out.println("驗(yàn)證失敗:"+e);
??}?
?}
?}
?上面的程序就指出了要引入的XMLSchema文件的位置。
?
?
?系統(tǒng)默認(rèn)輸出是UTF-8,這有可能導(dǎo)致出現(xiàn)亂碼。
5、Xpath例子:
JDOM的關(guān)于XPATH的api在org.jdom.xpath這個(gè)包里。這個(gè)包下,有一個(gè)抽象類XPath.java和實(shí)現(xiàn)類JaxenXPath.java,使用時(shí)先用XPath類的靜態(tài)方法newInstance(Stringxpath)得到XPath對(duì)象,然后調(diào)用它的selectNodes(Objectcontext)方法或selectSingleNode(Objectcontext)方法,前者根據(jù)xpath語(yǔ)句返回一組節(jié)點(diǎn)(List對(duì)象);后者根據(jù)一個(gè)xpath語(yǔ)句返回符合條件的第一個(gè)節(jié)點(diǎn)(Object類型)。請(qǐng)看jdom-1.0自帶的范例程序:
????它分析在web.xml文件中的注冊(cè)的servlet的個(gè)數(shù)及參數(shù)個(gè)數(shù),并輸出角色名。
web.xml文件:
<?xmlversion="1.0"encoding="ISO-8859-1"?>
<!--
<!DOCTYPEweb-app
???PUBLIC"-//SunMicrosystems,Inc.//DTDWebApplication2.2//EN"
???"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
-->
<web-app>
???<servlet>
???????<servlet-name>snoop</servlet-name>
???????<servlet-class>SnoopServlet</servlet-class>
???</servlet>
???<servlet>
???????<servlet-name>file</servlet-name>
???????<servlet-class>ViewFile</servlet-class>
???????<init-param>
???????????<param-name>initial</param-name>
???????????<param-value>1000</param-value>
???????????<description>Theinitialvalueforthecounter?<!--optional--></description>
???????</init-param>
???</servlet>
???<servlet-mapping>
???????<servlet-name>mv</servlet-name>
???????<url-pattern>*.wm</url-pattern>
???</servlet-mapping>
???<distributed/>
???<security-role>
?????<role-name>manager</role-name>
?????<role-name>director</role-name>
?????<role-name>president</role-name>
???</security-role>
</web-app>
處理程序:
importjava.io.*;
importjava.util.*;?
publicclassXPathReader{?????
???publicstaticvoidmain(String[]args)throwsIOException,JDOMException{
???????if(args.length!=1){
???????????System.err.println("Usage:javaXPathReaderweb.xml");
???????????return;
???????}
???????Stringfile?name=args[0];//從命令行輸入web.xml
???????PrintStream?out=System.out;
???????SAXBuilder?builder=new?SAXBuilder();
???????Document?doc=builder.build(new?File(filename));//得到Document對(duì)象
?
?
???????//Printservletinformation
???????XPath?servletPath=XPath.newInstance("http://servlet");//,選擇任意路徑下servlet元素
???????List?servlets=servletPath.selectNodes(doc);//返回所有的servlet元素。
???????out.println("This?WAR?has"+servlets.size()+"registered?servlets:");
???????Iterator?i=servlets.iterator();
???????while(i.hasNext()){//輸出servlet信息
???????????Element?servlet=(Element)i.next();
???????????out.print("\t"+servlet.getChild("servlet-name")
???????????????????????????????????.getTextTrim()+
?????????????????????"for"+servlet.getChild("servlet-class")
??????????????????????????????????????.getTextTrim());
???????????List?initParams=servlet.getChildren("init-param");
???????????out.println("(it?has"+initParams.size()+"initparams)");?
???????}?????????????
???????//Printsecurityroleinformation
???????XPath?rolePath=XPath.newInstance("http://security-role/role-name/text()");
???????List?roleNames=rolePath.selectNodes(doc);//得到所有的角色名
???????if(roleNames.size()==0){
???????????out.println("This?WAR?contains?no?roles");
???????}else{
???????????out.println("This?WAR?contains"+roleNames.size()+"roles:");
???????????i=roleNames.iterator();
???????????while(i.hasNext()){//輸出角色名
???????????????out.println("\t"+((Text)i.next()).getTextTrim());
???????????}
???????}
???}????
}
?
?
輸出結(jié)果:
C:\java>java??XPathReaderweb.xml
ThisWARhas2registeredservlets:
???????snoopforSnoopServlet(ithas0initparams)
???????fileforViewFile(ithas1initparams)
ThisWARcontains3roles:
???????manager
???????director
???????president
?
?
6、數(shù)據(jù)輸入要用到XML文檔要通過org.jdom.input包,反過來(lái)需要org.jdom.output。如前面所說(shuō),關(guān)是看API文檔就能夠使用。
我們的例子讀入XML文件exampleA.xml,加入一條處理指令,修改第一本書的價(jià)格和作者,并添加一條屬性,然后寫入文件exampleB.xml:
//exampleA.xml
<?xmlversion="1.0"encoding="GBK"?>
<bookList>
<book>
<name>Java編程入門</name>
<author>張三</author>
<publishDate>2002-6-6</publishDate>
<price>35.0</price>
</book>
<book>
<name>XML在Java中的應(yīng)用</name>
<author>李四</author>
<publishDate>2002-9-16</publishDate>
<price>92.0</price>
</book>
</bookList>
//testJDOM.java
importorg.jdom.*;
importorg.jdom.output.*;
importorg.jdom.input.*;
importjava.io.*;
publicclassTestJDOM{
publicstaticvoidmain(Stringargs[])throwsException{
SAXBuildersb=newSAXBuilder();
//從文件構(gòu)造一個(gè)Document,因?yàn)閄ML文件中已經(jīng)指定了編碼,所以這里不必了
Documentdoc=sb.build(newFileInputStream("exampleA.xml"));
ProcessingInstructionpi=newProcessingInstruction//加入一條處理指令
("xml-stylesheet","href=\"bookList.html.xsl\"type=\"text/xsl\"");
doc.addContent(pi);
Elementroot=doc.getRootElement();//得到根元素
java.util.Listbooks=root.getChildren();//得到根元素所有子元素的集合
Elementbook=(Element)books.get(0);//得到第一個(gè)book元素
//為第一本書添加一條屬性
Attributea=newAttribute("hot","true");
book.setAttribute(a);
Elementauthor=book.getChild("author");//得到指定的字元素
author.setText("王五");//將作者改為王五
//或Textt=newText("王五");book.addContent(t);
Elementprice=book.getChild("price");//得到指定的字元素
//修改價(jià)格,比較郁悶的是我們必須自己轉(zhuǎn)換數(shù)據(jù)類型,而這正是JAXB的優(yōu)勢(shì)
author.setText(Float.toString(50.0f));
Stringindent="";
booleannewLines=true;
XMLOutputteroutp=newXMLOutputter(indent,newLines,"GBK");
outp.output(doc,newFileOutputStream("exampleB.xml"));
}
};
執(zhí)行結(jié)果exampleB.xml:
<?xmlversion="1.0"encoding="GBK"?>
<bookList>
<bookhot=”true”>
<name>Java編程入門</name>
<author>50.0</author>
<publishDate>2002-6-6</publishDate>
<price>35.0</price>
</book>
<book>
<name>XML在Java中的應(yīng)用</name>
<author>李四</author>
<publishDate>2002-9-16</publishDate>
<price>92.0</price>
</book>
</bookList>
<?xml-stylesheethref="bookList.html.xsl"type="text/xsl"?>
在默認(rèn)情況下,JDOM的Element類的getText()這類的方法不會(huì)過濾空白字符,如果你需要過濾,用setTextTrim().
JDOM是一個(gè)開源項(xiàng)目,它基于樹型結(jié)構(gòu),利用純JAVA的技術(shù)對(duì)XML文檔實(shí)現(xiàn)解析、生成、序列化以及多種操作。
JDOM直接為JAVA編程服務(wù)。它利用更為強(qiáng)有力的JAVA語(yǔ)言的諸多特性(方法重載、集合概念以及映射),把SAX和DOM的功能有效地結(jié)合起來(lái)。
在使用設(shè)計(jì)上盡可能地隱藏原來(lái)使用XML過程中的復(fù)雜性。利用JDOM處理XML文檔將是一件輕松、簡(jiǎn)單的事。
JDOM在2000年的春天被BrettMcLaughlin和JasonHunter開發(fā)出來(lái),以彌補(bǔ)DOM及SAX在實(shí)際應(yīng)用當(dāng)中的不足之處。
這些不足之處主要在于SAX沒有文檔修改、隨機(jī)訪問以及輸出的功能,而對(duì)于DOM來(lái)說(shuō),JAVA程序員在使用時(shí)來(lái)用起來(lái)總覺得不太方便。
DOM的缺點(diǎn)主要是來(lái)自于由于Dom是一個(gè)接口定義語(yǔ)言(IDL),它的任務(wù)是在不同語(yǔ)言實(shí)現(xiàn)中的一個(gè)最低的通用標(biāo)準(zhǔn),并不是為JAVA特別設(shè)計(jì)的。JDOM的最新版本為JDOMBeta9。最近JDOM被收錄到JSR-102內(nèi),這標(biāo)志著JDOM成為了JAVA平臺(tái)組成的一部分。
二、JDOM包概覽
JDOM是由以下幾個(gè)包組成的
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文檔接口轉(zhuǎn)換為其他xml文檔接口
?
org.jdom.xpath???????????包含了對(duì)xml文檔xpath操作的類
三、JDOM類說(shuō)明
1、org.JDOM這個(gè)包里的類是你J解析xml文件后所要用到的所有數(shù)據(jù)類型。
Attribute
CDATA
Coment
DocType
Document
Element
EntityRef
Namespace
ProscessingInstruction
Text
2、org.JDOM.transform在涉及xslt格式轉(zhuǎn)換時(shí)應(yīng)使用下面的2個(gè)類
JDOMSource
JDOMResult
org.JDOM.input
3、輸入類,一般用于文檔的創(chuàng)建工作
SAXBuilder
DOMBuilder
ResultSetBuilder
4、org.JDOM.output輸出類,用于文檔轉(zhuǎn)換輸出
XMLOutputter
SAXOutputter
DomOutputter
JTreeOutputter
使用前注意事項(xiàng):
1.JDOM對(duì)于JAXP以及TRax的支持
JDOM支持JAXP1.1:你可以在程序中使用任何的parser工具類,默認(rèn)情況下是JAXP的parser。
制定特別的parser可用如下形式
SAXBuilder?parser
?=new?SAXBuilder("org.apache.crimson.parser.XMLReaderImpl");
?Document?doc=parser.build("http://www.cafeconleche.org/");
?//work?with?the?document...
JDOM也支持TRaX:XSLT可通過JDOMSource以及JDOMResult類來(lái)轉(zhuǎn)換(參見以后章節(jié))
2.注意在JDOM里文檔(Document)類由org.JDOM.Document來(lái)表示。這要與org.w3c.dom中的Document區(qū)別開,這2種格式如何轉(zhuǎn)換在后面會(huì)說(shuō)明。
以下如無(wú)特指均指JDOM里的Document。
四、JDOM主要使用方法
1.Ducument類
(1)Document的操作方法:
Element?root=new?Element("GREETING");
Document?doc=new?Document(root);
root.setText("Hello?JDOM!");
或者簡(jiǎn)單的使用Document?doc=new?Document(new?Element("GREETING").setText("HelloJDOM!t"));
這點(diǎn)和DOM不同。Dom則需要更為復(fù)雜的代碼,如下:
DocumentBuilderFactory?factory=DocumentBuilderFactory.newInstance();
DocumentBuilder?builder=factory.newDocumentBuilder();
Document?doc=builder.newDocument();
Element?root=doc.createElement("root");
Text?text=doc.createText("This?is?the?root");
root.appendChild(text);
doc.appendChild(root);
注意事項(xiàng):JDOM不允許同一個(gè)節(jié)點(diǎn)同時(shí)被2個(gè)或多個(gè)文檔相關(guān)聯(lián),要在第2個(gè)文檔中使用原來(lái)老文檔中的節(jié)點(diǎn)的話。首先需要使用detach()把這個(gè)節(jié)點(diǎn)分開來(lái)。
(2)從文件、流、系統(tǒng)ID、URL得到Document對(duì)象:
DOMBuilder?builder=new?DOMBuilder();
Document?doc=builder.build(new?File("jdom_test.xml"));
SAXBuilder?builder=new?SAXBuilder();
Document?doc=builder.build(url);
在新版本中DOMBuilder已經(jīng)Deprecated掉DOMBuilder.builder(url),用SAX效率會(huì)比較快。
這里舉一個(gè)小例子,為了簡(jiǎn)單起見,使用String對(duì)象直接作為xml數(shù)據(jù)源:
?Public?jdomTest(){
???String?textXml=null;
???textXml="<note>";
???textXml=textXml+
???????"<to>aaa</to><from>bbb</from><heading>ccc</heading><body>ddd</body>";
???textXml=textXml+"</note>";
???SAXBuilderbuilder=newSAXBuilder();
???Document?doc=null;
???Reader?in=new?StringReader(textXml);
???try{
?????doc=builder.build(in);
?????Element?root=doc.getRootElement();
?????List?ls=root.getChildren();//注意此處取出的是root節(jié)點(diǎn)下面的一層的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之間的相互轉(zhuǎn)換使用方法,簡(jiǎn)單!
DOMBuilder?builder=new?DOMBuilder();
org.jdom.Document?jdomDocument=builder.build(domDocument);
DOMOutputter?converter=new?DOMOutputter();//workwiththeJDOMdocument…
org.w3c.dom.Document?domDocument=converter.output(jdomDocument);
//workwiththeDOMdocument…
2.XML文檔輸出
XMLOutPutter類:
JDOM的輸出非常靈活,支持很多種io格式以及風(fēng)格的輸出
Document?doc=newDocument(...);
XMLOutputter?outp=new?XMLOutputter();
outp.output(doc,fileOutputStream);//Rawoutput
outp.setTextTrim(true);//Compressed?output
outp.output(doc,socket.getOutputStream());
outp.setIndent("");//Pretty?output
outp.setNewlines(true);
outp.output(doc,System.out);
詳細(xì)請(qǐng)參閱最新的JDOMAPI手冊(cè)
3.Element類:
(1)瀏覽Element樹
Element?root=doc.getRootElement();//獲得根元素element
List?allChildren=root.getChildren();//獲得所有子元素的一個(gè)list
List?namedChildren=root.getChildren("name");//獲得指定名稱子元素的list
Element?child=root.getChild("name");//獲得指定名稱的第一個(gè)子元素
JDOM給了我們很多很靈活的使用方法來(lái)管理子元素(這里的List是java.util.List)
List?allChildren=root.getChildren();
allChildren.remove(3);//刪除第四個(gè)子元素
allChildren.removeAll(root.getChildren("jack"));//刪除叫“jack”的子元素
root.removeChildren("jack");//便捷寫法
allChildren.add(newElement("jane"));//加入
root.addContent(newElement("jane"));//便捷寫法
allChildren.add(0,newElement("first"));
(2)移動(dòng)Elements:
在JDOM里很簡(jiǎn)單
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);//出錯(cuò)!
補(bǔ)充:糾錯(cuò)性
JDOM的Element構(gòu)造函數(shù)(以及它的其他函數(shù))會(huì)檢查element是否合法。
而它的add/remove方法會(huì)檢查樹結(jié)構(gòu),檢查內(nèi)容如下:
1.在任何樹中是否有回環(huán)節(jié)點(diǎn)
2.是否只有一個(gè)根節(jié)點(diǎn)
3.是否有一致的命名空間(Namespaces)
(3)Element的text內(nèi)容讀取
<description>
A?cool?demo
</description>
//The?text?is?directly?available
//Returns"\n?A?cool?demo\n"
String?desc=element.getText();
//There's?a?convenient?short?cut
//Returns?"A?cool?demo"
String?desc=element.getTextTrim();
(4)Elment內(nèi)容修改
element.setText("Anewdescription");
3.可正確解釋特殊字符
element.setText("<xml>content");
4.CDATA的數(shù)據(jù)寫入、讀出
element.addContent(newCDATA("<xml>content"));
String?noDifference=element.getText();
混合內(nèi)容
element可能包含很多種內(nèi)容,比如說(shuō)
<table>
<!?Some?comment-->
Some?text
<tr>Some?child?element</tr>
</table>
取table的子元素tr
String?text=table.getTextTrim();
Element?tr=table.getChild("tr");
也可使用另外一個(gè)比較簡(jiǎn)單的方法
List?mixedCo=table.getContent();
Iterator?itr=mixedCo.iterator();
while(itr.hasNext()){
Objecto=i.next();
if(o?instanceof?Comment){...}
//這里可以寫成Comment,Element,Text,CDATA,ProcessingInstruction,或者是EntityRef的類型
}
//現(xiàn)在移除Comment,注意這里游標(biāo)應(yīng)為1。這是由于回車鍵也被解析成Text類的緣故,所以Comment項(xiàng)應(yīng)為1。
mixedCo.remove(1);
4.Attribute類
<table?width="100%"?border="0"></table>
String?width=table.getAttributeValue("width");//獲得attribute
Int?border=table.getAttribute("border").getIntValue();
table.setAttribute("vspace","0");//設(shè)置attribute
table.removeAttribute("vspace");//刪除一個(gè)或全部attribute
table.getAttributes().clear();
5.處理指令(ProcessingInstructions)操作
一個(gè)Pls的例子
<?br?>
<?cocoon-processtype="xslt"?>
?????????|???????|
?????????|???????|
???????目標(biāo)????數(shù)據(jù)
處理目標(biāo)名稱(Target)
String?target=pi.getTarget();
獲得所有數(shù)據(jù)(data),在目標(biāo)(target)以后的所有數(shù)據(jù)都會(huì)被返回。
String?data=pi.getData();
String?type=pi.getValue("type");獲得指定屬性的數(shù)據(jù)
List?ls=pi.getNames();獲得所有屬性的名稱
6.命名空間操作
<xhtml:html
?xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xhtml:title>HomePage</xhtml:title>
</xhtml:html>
Namespace?xhtml=Namespace.getNamespace("xhtml","http://www.w3.org/1999/xhtml");
List?kids=html.getChildren("title",xhtml);
Element?kid=html.getChild("title",xhtml);
kid.addContent(newElement("table",xhtml));
7.XSLT格式轉(zhuǎn)換
使用以下函數(shù)可對(duì)XSLT轉(zhuǎn)換
最后如果你需要使用w3c的Document則需要轉(zhuǎn)換一下。
Public?static?Document?transform(String?stylesheet,Document?in)
???????????????????????????????????????Throws?JDOMException{
????try{
??????Transformer?transformer=TransformerFactory.newInstance()
????????????????????????????.new?Transformer(newstreamSource(stylesheet));
??????JDOMResult?out=new?JDOMResult();
??????transformer.transform(newJDOMSource(in),out);
??????return?out.getDocument();
????}
????catch(TransformerException?e){
??????throw?newJDOMException("XSLT?Trandformation?failed",e);
????}
??}
五、用例:
1、生成xml文檔:
?
?
Public?class?WriteXML{
???Public?void?BuildXML()?throws?Exception{
???????Element?root,student,number,name,age;????????
???????root=new?Element("student-info");//生成根元素:student-info
???????student=new?Element("student");//生成元素:student(number,name,age)????????????????????????????
???????number=new?Element("number");
???????name=new?Element("name");
???????age=new?Element("age");
???????Document?doc=new?Document(root);//將根元素植入文檔doc中
???????number.setText("001");
???????name.setText("lnman");
???????age.setText("24");
???????student.addContent(number);
???????student.addContent(name);
???????student.addContent(age);
???????root.addContent(student);
???????Format?format=Format.getCompactFormat();
???????format.setEncoding("gb2312");//設(shè)置xml文件的字符為gb2312
???????format.setIndent("???");//設(shè)置xml文件的縮進(jìn)為4個(gè)空格
???????XMLOutputterXML?Out=new?XMLOutputter(format);//元素后換行一層元素縮四格
???????XMLOut.output(doc,new?FileOutputStream("studentinfo.xml"));?
}
???Public?static?void?main(String[]?args)?throws?Exception{
???????WriteXML?w=new?WriteXML();
???????System.out.println("NowwebuildanXMLdocument.....");
???????w.BuildXML();
???????System.out.println("finished!");
}
}
生成的xml文檔為:
<?xmlversion="1.0"encoding="gb2312"?>
<student-info>
???<student>
???????<number>001</number>
???????<name>lnman</name>
???????<age>24</age>
???</student>
</student-info>
?
?
創(chuàng)建XML文檔2:
?Public?class?CreateXML{
?Public?void?Create(){
??try{
???Document?doc=new?Document();??
???ProcessingInstruction?pi=new?ProcessingInstruction("xml-stylesheet","type="text/xsl"href="test.xsl"");
???doc.addContent(pi);???
???Namespace?ns=Namespace.getNamespace("http://www.bromon.org");
???Namespace?ns2=Namespace.getNamespace("other","http://www.w3c.org");
???Element?root=new?Element("根元素",ns);
???root.addNamespaceDeclaration(ns2);
???doc.setRootElement(root);
???Elemente?l1=new?Element("元素一");
???el1.setAttribute("屬性","屬性一");???
???Text?text1=new?Text("元素值");
????????????Element?em=new?Element("元素二").addContent("第二個(gè)元素");
???el1.addContent(text1);
????????????el1.addContent(em);????????????
????????????Elementel2=newElement("元素三").addContent("第三個(gè)元素");
????????????root.addContent(el1);
????????????root.addContent(el2);????????????
????????????//縮進(jìn)四個(gè)空格,自動(dòng)換行,gb2312編碼
????????????XMLOutputter?outputter=new?XMLOutputter("?",true,"GB2312");
????????????outputter.output(doc,newFileWriter("test.xml"));
????????}catch(Exceptione)?{
?????????System.out.println(e);
????????}
????}????
????Public?static?void?main(String?args[]){
?????New?CreateXML().Create();
????}????
?}
2、讀取xml文檔的例子:
importorg.jdom.output.*;
importorg.jdom.input.*;
importorg.jdom.*;
importjava.io.*;
importjava.util.*;
public?class?ReadXML{
???public?static?void?main(String[]?args)?throws?Exception{
???????SAXBuilder?builder=new?SAXBuilder();
???????Document?read_doc=builder.build("studentinfo.xml");
???????Element?stu=read_doc.getRootElement();
???????List?list=stu.getChildren("student");
???????for(int?i=0;i<list.size();i++){
???????????Element?e=(Element)list.get(i);
???????????String?str_number=e.getChildText("number");
???????????String?str_name=e.getChildText("name");
???????????String?str_age=e.getChildText("age");
???????????System.out.println("---------STUDENT--------------");
???????????System.out.println("NUMBER:"+str_number);
???????????System.out.println("NAME:"+str_name);
???????????System.out.println("AGE:"+str_age);
???????????System.out.println("------------------------------");
???????????System.out.println();
???????}?
??????}
}
3、DTD驗(yàn)證的:
?Public?class?XMLWithDTD{
?Public?void?validate()?{
??try{
???SAXBuilder?builder=new?SAXBuilder(true);
???builder.setFeature("http://xml.org/sax/features/validation";,true);
???Document?doc=builder.build(newFileReader("author.xml"));???
???System.out.println("搞掂");
???XMLOutputter?outputter=new?XMLOutputter();
???outputter.output(doc,System.out);
??}catch(Exceptione){
???System.out.println(e);
??}??
?}
?Public?static?void?main(String?args[]){
??new?XMLWithDTD().validate();
?}?
?}
?需要說(shuō)明的是,這個(gè)程序沒有指明使用哪個(gè)DTD文件。DTD文件的位置是在XML中指定的,而且DTD不支持命名空間,一個(gè)XML只能引用一個(gè)DTD,所以程序直接讀取XML中指定的DTD,程序本身不用指定。不過這樣一來(lái),好象就只能使用外部式的DTD引用方式了?高人指點(diǎn)。
?
?
4、XMLSchema驗(yàn)證的:
?Public?classXMLWithSchema{
?String?xml="test.xml";
?String?schema="test-schema.xml";
?Public?void?validate(){
??try{
???SAXBuilder?builder=new?SAXBuilder(true);
???//指定約束方式為XMLschema
???builder.setFeature("http://apache.org/xml/features/validation/schema";,?true);
???//導(dǎo)入schema文件
builder.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation";,schema);
???Document?doc=builder.build(new?FileReader(xml));???
???System.out.println("搞掂");
???XMLOutputter?outputter=new?XMLOutputter();
???outputter.output(doc,System.out);
??}catch(Exceptione){
???System.out.println("驗(yàn)證失敗:"+e);
??}?
?}
?}
?上面的程序就指出了要引入的XMLSchema文件的位置。
?
?
?系統(tǒng)默認(rèn)輸出是UTF-8,這有可能導(dǎo)致出現(xiàn)亂碼。
5、Xpath例子:
JDOM的關(guān)于XPATH的api在org.jdom.xpath這個(gè)包里。這個(gè)包下,有一個(gè)抽象類XPath.java和實(shí)現(xiàn)類JaxenXPath.java,使用時(shí)先用XPath類的靜態(tài)方法newInstance(Stringxpath)得到XPath對(duì)象,然后調(diào)用它的selectNodes(Objectcontext)方法或selectSingleNode(Objectcontext)方法,前者根據(jù)xpath語(yǔ)句返回一組節(jié)點(diǎn)(List對(duì)象);后者根據(jù)一個(gè)xpath語(yǔ)句返回符合條件的第一個(gè)節(jié)點(diǎn)(Object類型)。請(qǐng)看jdom-1.0自帶的范例程序:
????它分析在web.xml文件中的注冊(cè)的servlet的個(gè)數(shù)及參數(shù)個(gè)數(shù),并輸出角色名。
web.xml文件:
<?xmlversion="1.0"encoding="ISO-8859-1"?>
<!--
<!DOCTYPEweb-app
???PUBLIC"-//SunMicrosystems,Inc.//DTDWebApplication2.2//EN"
???"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
-->
<web-app>
???<servlet>
???????<servlet-name>snoop</servlet-name>
???????<servlet-class>SnoopServlet</servlet-class>
???</servlet>
???<servlet>
???????<servlet-name>file</servlet-name>
???????<servlet-class>ViewFile</servlet-class>
???????<init-param>
???????????<param-name>initial</param-name>
???????????<param-value>1000</param-value>
???????????<description>Theinitialvalueforthecounter?<!--optional--></description>
???????</init-param>
???</servlet>
???<servlet-mapping>
???????<servlet-name>mv</servlet-name>
???????<url-pattern>*.wm</url-pattern>
???</servlet-mapping>
???<distributed/>
???<security-role>
?????<role-name>manager</role-name>
?????<role-name>director</role-name>
?????<role-name>president</role-name>
???</security-role>
</web-app>
處理程序:
importjava.io.*;
importjava.util.*;?
publicclassXPathReader{?????
???publicstaticvoidmain(String[]args)throwsIOException,JDOMException{
???????if(args.length!=1){
???????????System.err.println("Usage:javaXPathReaderweb.xml");
???????????return;
???????}
???????Stringfile?name=args[0];//從命令行輸入web.xml
???????PrintStream?out=System.out;
???????SAXBuilder?builder=new?SAXBuilder();
???????Document?doc=builder.build(new?File(filename));//得到Document對(duì)象
?
?
???????//Printservletinformation
???????XPath?servletPath=XPath.newInstance("http://servlet");//,選擇任意路徑下servlet元素
???????List?servlets=servletPath.selectNodes(doc);//返回所有的servlet元素。
???????out.println("This?WAR?has"+servlets.size()+"registered?servlets:");
???????Iterator?i=servlets.iterator();
???????while(i.hasNext()){//輸出servlet信息
???????????Element?servlet=(Element)i.next();
???????????out.print("\t"+servlet.getChild("servlet-name")
???????????????????????????????????.getTextTrim()+
?????????????????????"for"+servlet.getChild("servlet-class")
??????????????????????????????????????.getTextTrim());
???????????List?initParams=servlet.getChildren("init-param");
???????????out.println("(it?has"+initParams.size()+"initparams)");?
???????}?????????????
???????//Printsecurityroleinformation
???????XPath?rolePath=XPath.newInstance("http://security-role/role-name/text()");
???????List?roleNames=rolePath.selectNodes(doc);//得到所有的角色名
???????if(roleNames.size()==0){
???????????out.println("This?WAR?contains?no?roles");
???????}else{
???????????out.println("This?WAR?contains"+roleNames.size()+"roles:");
???????????i=roleNames.iterator();
???????????while(i.hasNext()){//輸出角色名
???????????????out.println("\t"+((Text)i.next()).getTextTrim());
???????????}
???????}
???}????
}
?
?
輸出結(jié)果:
C:\java>java??XPathReaderweb.xml
ThisWARhas2registeredservlets:
???????snoopforSnoopServlet(ithas0initparams)
???????fileforViewFile(ithas1initparams)
ThisWARcontains3roles:
???????manager
???????director
???????president
?
?
6、數(shù)據(jù)輸入要用到XML文檔要通過org.jdom.input包,反過來(lái)需要org.jdom.output。如前面所說(shuō),關(guān)是看API文檔就能夠使用。
我們的例子讀入XML文件exampleA.xml,加入一條處理指令,修改第一本書的價(jià)格和作者,并添加一條屬性,然后寫入文件exampleB.xml:
//exampleA.xml
<?xmlversion="1.0"encoding="GBK"?>
<bookList>
<book>
<name>Java編程入門</name>
<author>張三</author>
<publishDate>2002-6-6</publishDate>
<price>35.0</price>
</book>
<book>
<name>XML在Java中的應(yīng)用</name>
<author>李四</author>
<publishDate>2002-9-16</publishDate>
<price>92.0</price>
</book>
</bookList>
//testJDOM.java
importorg.jdom.*;
importorg.jdom.output.*;
importorg.jdom.input.*;
importjava.io.*;
publicclassTestJDOM{
publicstaticvoidmain(Stringargs[])throwsException{
SAXBuildersb=newSAXBuilder();
//從文件構(gòu)造一個(gè)Document,因?yàn)閄ML文件中已經(jīng)指定了編碼,所以這里不必了
Documentdoc=sb.build(newFileInputStream("exampleA.xml"));
ProcessingInstructionpi=newProcessingInstruction//加入一條處理指令
("xml-stylesheet","href=\"bookList.html.xsl\"type=\"text/xsl\"");
doc.addContent(pi);
Elementroot=doc.getRootElement();//得到根元素
java.util.Listbooks=root.getChildren();//得到根元素所有子元素的集合
Elementbook=(Element)books.get(0);//得到第一個(gè)book元素
//為第一本書添加一條屬性
Attributea=newAttribute("hot","true");
book.setAttribute(a);
Elementauthor=book.getChild("author");//得到指定的字元素
author.setText("王五");//將作者改為王五
//或Textt=newText("王五");book.addContent(t);
Elementprice=book.getChild("price");//得到指定的字元素
//修改價(jià)格,比較郁悶的是我們必須自己轉(zhuǎn)換數(shù)據(jù)類型,而這正是JAXB的優(yōu)勢(shì)
author.setText(Float.toString(50.0f));
Stringindent="";
booleannewLines=true;
XMLOutputteroutp=newXMLOutputter(indent,newLines,"GBK");
outp.output(doc,newFileOutputStream("exampleB.xml"));
}
};
執(zhí)行結(jié)果exampleB.xml:
<?xmlversion="1.0"encoding="GBK"?>
<bookList>
<bookhot=”true”>
<name>Java編程入門</name>
<author>50.0</author>
<publishDate>2002-6-6</publishDate>
<price>35.0</price>
</book>
<book>
<name>XML在Java中的應(yīng)用</name>
<author>李四</author>
<publishDate>2002-9-16</publishDate>
<price>92.0</price>
</book>
</bookList>
<?xml-stylesheethref="bookList.html.xsl"type="text/xsl"?>
在默認(rèn)情況下,JDOM的Element類的getText()這類的方法不會(huì)過濾空白字符,如果你需要過濾,用setTextTrim().