天天看點

dom4j api 詳解

1、DOM4J簡介

    DOM4J是 dom4j.org 出品的一個開源 XML 解析包。DOM4J應用于 Java 平台,采用了 Java 集合架構并完全支援 DOM,SAX 和 JAXP。

    DOM4J 使用起來非常簡單。隻要你了解基本的 XML-DOM 模型,就能使用。

    Dom:把整個文檔作為一個對象。

  DOM4J 最大的特色是使用大量的接口。它的主要接口都在org.dom4j裡面定義:

Attribute 定義了 XML 的屬性。
Branch 指能夠包含子節點的節點。如XML元素(Element)和文檔(Docuemnts)定義了一個公共的行為
CDATA 定義了 XML CDATA 區域
CharacterData 是一個辨別接口,辨別基于字元的節點。如CDATA,Comment, Text.
Comment 定義了 XML 注釋的行為
Document 定義了XML 文檔
DocumentType 定義 XML DOCTYPE 聲明
Element 定義XML 元素
ElementHandler 定義了Element 對象的處理器
ElementPath 被 ElementHandler 使用,用于取得目前正在處理的路徑層次資訊
Entity 定義 XML entity
Node 為dom4j中所有的XML節點定義了多态行為
NodeFilter 定義了在dom4j 節點中産生的一個濾鏡或謂詞的行為(predicate)
ProcessingInstruction 定義 XML 處理指令
Text 定義 XML 文本節點
Visitor 用于實作 Visitor模式
XPath 在分析一個字元串後會提供一個 XPath 表達式

接口之間的繼承關系如下:

interface java.lang.Cloneable

    interface org.dom4j.Node

           interface org.dom4j.Attribute

           interface org.dom4j.Branch

                  interface org.dom4j.Document

                  interface org.dom4j.Element

           interface org.dom4j.CharacterData

                  interface org.dom4j.CDATA

                  interface org.dom4j.Comment

                  interface org.dom4j.Text

           interface org.dom4j.DocumentType

           interface org.dom4j.Entity

           interface org.dom4j.ProcessingInstruction

2、XML文檔操作1

2.1、讀取XML文檔:

     讀寫XML文檔主要依賴于org.dom4j.io包,有DOMReader和SAXReader兩種方式。因為利用了相同的接口,它們的調用方式是一樣的。

public static Document load(String filename) {

Document document = null;

try {

SAXReader saxReader = new SAXReader();

document = saxReader.read(new File(filename));  //讀取XML檔案,獲得document對象

} catch (Exception ex) {

ex.printStackTrace();

}

return document;

}   

public static Document load(URL url) {

Document document = null;

try {

SAXReader saxReader = new SAXReader();

document = saxReader.read(url);  //讀取XML檔案,獲得document對象

} catch (Exception ex) {

ex.printStackTrace();

}

return document;

}

//讀取指定的xml檔案之後傳回一個Document對象,這個對象代表了整個XML文檔,用于各種Dom運算。執照XML檔案頭所定義的編碼來轉換。

2.2、擷取根節點

根節點是xml分析的開始,任何xml分析工作都需要從根開始

Xml xml = new Xml();

Document dom = xml.load(path + "/" + file);

Element root = dom.getRootElement();

2.3、. 新增一個節點以及其下的子節點與資料

Element menuElement = root.addElement("menu");

Element engNameElement = menuElement.addElement("engName");

engNameElement.setText(catNameEn);

Element chiNameElement = menuElement.addElement("chiName");

chiNameElement.setText(catName);

2.4、 寫入XML檔案

注意檔案操作的包裝類是亂碼的根源

public static boolean doc2XmlFile(Document document, String filename) {

boolean flag = true;

try {

XMLWriter writer = new XMLWriter( new OutputStreamWriter(new FileOutputStream(filename),"UTF-8"));

writer.write(document);

writer.close();

} catch (Exception ex) {

flag = false;

ex.printStackTrace();

}

System.out.println(flag);

return flag;

}

    Dom4j通過XMLWriter将Document對象表示的XML樹寫入指定的檔案,并使用OutputFormat格式對象指定寫入的風格和編碼方法。調用OutputFormat.createPrettyPrint()方法可以獲得一個預設的pretty print風格的格式對象。對OutputFormat對象調用setEncoding()方法可以指定XML檔案的編碼方法。

public void writeTo(OutputStream out, String encoding) throws UnsupportedEncodingException, IOException {

       OutputFormat format = OutputFormat.createPrettyPrint();

       format.setEncoding("gb2312");

       XMLWriter writer = new XMLWriter(System.out,format);

       writer.write(doc);

       writer.flush();

       return;

}

2. 5、周遊xml節點

       對Document對象調用getRootElement()方法可以傳回代表根節點的Element對象。擁有了一個Element對象後,可以對該對象調用elementIterator()方法獲得它的子節點的Element對象們的一個疊代器。使用(Element)iterator.next()方法周遊一個iterator并把每個取出的元素轉化為Element類型。

public boolean isOnly(String catNameEn,HttpServletRequest request,String xml) {

boolean flag = true;

String path = request.getRealPath("");

Document doc = load(path+"/"+xml);

Element root = doc.getRootElement();

for (Iterator i = root.elementIterator(); i.hasNext();) {

Element el = (Element) i.next();

if(catNameEn.equals(el.elementTextTrim("engName"))){

flag = false;

break;

}

}

return flag;

}

2.6、建立xml檔案

public static void main(String args[]){

String fileName="c:/text.xml";

Document document=DocumentHelper.createDocument();//建立document對象,用來操作xml檔案

Element booksElement=document.addElement("books");//建立根節點

booksElement.addComment("This is a test for dom4j ");//加入一行注釋

Element bookElement=booksElement.addElement("book");//添加一個book節點

bookElement.addAttribute("show","yes");//添加屬性内容

Element titleElement=bookElement.addElement("title");//添加文本節點

titleElement.setText("ajax in action");//添加文本内容

try{

XMLWriter writer=new XMLWriter(new FileWriter(new File(fileName)));

writer.write(document);

writer.close();

}catch(Exception e){

e.printStackTrace();

}

}

2.7、修改節點屬性

public static void modifyXMLFile() {

String oldStr = "c:/text.xml";

String newStr = "c:/text1.xml";

Document document = null;

//修改節點的屬性

try {

SAXReader saxReader = new SAXReader(); // 用來讀取xml文檔

document = saxReader.read(new File(oldStr)); // 讀取xml文檔

List list = document.selectNodes("/books/book/@show");// 用xpath查找節點book的屬性

Iterator iter = list.iterator();

while (iter.hasNext()) {

Attribute attribute = (Attribute) iter.next();

if (attribute.getValue().equals("yes")) 

    attribute.setValue("no");

}

} catch (Exception e) {

    e.printStackTrace();

}

//修改節點的内容

try {

SAXReader saxReader = new SAXReader(); // 用來讀取xml文檔

document = saxReader.read(new File(oldStr)); // 讀取xml文檔

List list = document.selectNodes("/books/book/title");// 用xpath查找節點book的内容

Iterator iter = list.iterator();

while (iter.hasNext()) {

Element element = (Element) iter.next();

element.setText("xxx");// 設定相應的内容

}

} catch (Exception e) {

    e.printStackTrace();

}

try {

XMLWriter writer = new XMLWriter(new FileWriter(new File(newStr)));

writer.write(document);

writer.close();

} catch (Exception ex) {

    ex.printStackTrace();

}

}

2.8、删除節點

public static void removeNode() {

String oldStr = "c:/text.xml";

String newStr = "c:/text1.xml";

Document document = null;

try {

SAXReader saxReader = new SAXReader();// 用來讀取xml文檔

document = saxReader.read(new File(oldStr));// 讀取xml文檔

List list = document.selectNodes("/books/book");// 用xpath查找對象

Iterator iter = list.iterator();

while (iter.hasNext()) {

Element bookElement = (Element) iter.next();

// 建立疊代器,用來查找要删除的節點,疊代器相當于指針,指向book下所有的title節點

Iterator iterator = bookElement.elementIterator("title");

while (iterator.hasNext()) {

Element titleElement = (Element) iterator.next();

if (titleElement.getText().equals("ajax in action")) {

bookElement.remove(titleElement);

}

}

}

} catch (Exception e) {

e.printStackTrace();

}

try {

XMLWriter writer = new XMLWriter(new FileWriter(new File(newStr)));

writer.write(document);

writer.close();

} catch (Exception ex) {

ex.printStackTrace();

}

}

2、XML文檔操作2

2.1、Document對象相關        

1、讀取XML檔案,獲得document對象.      

       SAXReader reader = new SAXReader();  

      Document   document = reader.read(new File("input.xml"));      

2、解析XML形式的文本,得到document對象.      

             String text = "<members></members>";      

             Document document = DocumentHelper.parseText(text);      

3、主動建立document對象.      

             Document document = DocumentHelper.createDocument();      

             Element root = document.addElement("members");// 建立根節點      

2.2、節點相關        

1、擷取文檔的根節點.      

Element rootElm = document.getRootElement();      

2、取得某節點的單個子節點.      

Element memberElm=root.element("member");// "member"是節點名      

3.取得節點的文字      

String text=memberElm.getText();     

String text=root.elementText("name");這個是取得根節點下的name位元組點的文字.       

4.取得某節點下指定名稱的所有節點并進行周遊.      

List nodes = rootElm.elements("member");      

for (Iterator it = nodes.iterator(); it.hasNext();) {      

    Element elm = (Element) it.next();      

   // do something      

}      

5.對某節點下的所有子節點進行周遊.      

            for(Iterator it=root.elementIterator();it.hasNext();){      

                 Element element = (Element) it.next();      

                // do something      

             }      

6.在某節點下添加子節點.      

Element ageElm = newMemberElm.addElement("age");      

7.設定節點文字.      

ageElm.setText("29");      

8.删除某節點.      

parentElm.remove(childElm);    // childElm是待删除的節點,parentElm是其父節點      

9.添加一個CDATA節點.      

         Element contentElm = infoElm.addElement("content");      

         contentElm.addCDATA(diary.getContent());      

2.3、屬性相關.      

1.取得節點的指定的屬性      

             Element root=document.getRootElement();          

             Attribute attribute=root.attribute("size");    // 屬性名name      

2.取得屬性的文字      

    String text=attribute.getText();    

String text2=root.element("name").attributeValue("firstname");

//這個是取得根節點下name位元組點的firstname屬性的值.      

3.周遊某節點的所有屬性      

Element root=document.getRootElement();

for(Iterator it=root.attributeIterator();it.hasNext();){

Attribute attribute = (Attribute) it.next();

String text=attribute.getText();

System.out.println(text);

}

4.設定某節點的屬性和文字.      

newMemberElm.addAttribute("name", "sitinspring");    

5.設定屬性的文字      

             Attribute attribute=root.attribute("name");      

             attribute.setText("sitinspring");      

6.删除某屬性      

             Attribute attribute=root.attribute("size");// 屬性名name      

             root.remove(attribute);      

2.4、将文檔寫入XML檔案.      

1.文檔中全為英文,不設定編碼,直接寫入.      

XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));      

writer.write(document);      

writer.close();      

2.文檔中含有中文,設定編碼格式再寫入.      

OutputFormat format = OutputFormat.createPrettyPrint();

format.setEncoding("GBK");    // 指定XML編碼

XMLWriter writer = new XMLWriter(new FileWriter("output.xml"),format);

writer.write(document);

writer.close();

2.5、字元串與XML的轉換      

1.将字元串轉化為XML      

String text = "<members> <member>sitinspring</member> </members>";      

Document document = DocumentHelper.parseText(text);      

2.将文檔或節點的XML轉化為字元串.      

SAXReader reader = new SAXReader();

Document document = reader.read(new File("input.xml"));

Element root=document.getRootElement();

String docXmlText=document.asXML();

String rootXmlText=root.asXML();

Element memberElm=root.element("member");

String memberXmlText=memberElm.asXML();

3、dom4j的事件處理模型涉及的類和接口:

3.1、類:SAXReader

         public void addHandler(String path,ElementHandler handler)

     當解析到path指定的路徑時,将調用參數handler指定的處理器。針對不同的節點可以添加多個handler執行個體。或者調用預設的Handler setDefaultHandler(ElementHandler handler);

3.2、接口ElementHandler

         public void onStart(ElementPath path)

     該方法在解析到元素的開始标簽時被調用。

         public void onEnd(ElementPath path)

     該方法在解析到元素的結束标簽時被調用

3.3、接口:ElementPath (假設有參數:ElementPath path)

         public void addHandler(String path,ElementHandler)

     該方法與SAXReader類中的addHandler()方法的作用相同。路徑path可以是絕對路徑(路徑以/開頭),也可以是相對路徑(假設是目前路徑的子節點路徑)。

         public void removeHandler(String path)

     移除指定路徑上的ElementHandler執行個體。路徑可以是相對路徑,也可以是絕對路徑。

         public String getPath()

     該方法得到目前節點的路徑。該方法傳回的是完整的絕對路徑

         public Element getCurrent()

     該方法得到目前節點。

3.3、Element類 

getQName() 元素的QName對象
getNamespace() 元素所屬的Namespace對象
getNamespacePrefix() 元素所屬的Namespace對象的prefix
getNamespaceURI() 元素所屬的Namespace對象的URI
getName() 元素的local name
getQualifiedName() 元素的qualified name
getText() 元素所含有的text内容,如果内容為空則傳回一個空字元串而不是null
getTextTrim() 元素所含有的text内容,其中連續的空格被轉化為單個空格,該方法不會傳回null
attributeIterator() 元素屬性的iterator,其中每個元素都是Attribute對象
attributeValue() 元素的某個指定屬性所含的值
elementIterator() 元素的子元素的iterator,其中每個元素都是Element對象
element() 元素的某個指定(qualified name或者local name)的子元素
elementText() 元素的某個指定(qualified name或者local name)的子元素中的text資訊
getParent 元素的父元素
getPath() 元素的XPath表達式,其中父元素的qualified name和子元素的qualified name之間使用"/"分隔
isTextOnly() 是否該元素隻含有text或是空元素
isRootElement() 是否該元素是XML樹的根節點