1. 程式人生 > >Dom4j 解析XML例項

Dom4j 解析XML例項

解析XML的方式有很多,本文介紹使用dom4j解析xml。

1、環境準備

(1)下載dom4j-1.6.1.jar

(2)下載junit-4.10.jar

2、溫馨提示

解析XML過程是通過獲取Document物件,然後繼續獲取各個節點以及屬性等操作,因此獲取Document物件是第一步,大體說來,有三種方式:

(1)自己建立Document物件

Document document = DocumentHelper.createDocument();  
        Element root = document.addElement("students"); 

其中students是根節點,可以繼續新增其他節點等操作。

(2)讀取XML檔案獲取Document物件

//建立SAXReader物件  
        SAXReader reader = new SAXReader();  
        //讀取檔案 轉換成Document  
        Document document = reader.read(new File("XXXX.xml"));  

(3)讀取XML文字內容獲取Document物件

String xmlStr = "<students>......</students>";  
        Document document = DocumentHelper.parseText(xmlStr);
3、示例

(1)xml檔案內容如下

<?xml version="1.0" encoding="UTF-8"?>  
<students>  
    <student1 id="001">  
        <微信公眾號>@殘缺的孤獨</微信公眾號>  
        <學號>20140101</學號>  
        <地址>北京海淀區</地址>  
        <座右銘>要麼強大,要麼聽話</座右銘>  
    </student1>  
    <student2 id="002">  
        <新浪微博>@殘缺的孤獨</新浪微博>  
        <學號>20140102</學號>  
        <地址>北京朝陽區</地址>  
        <座右銘>在哭泣中學會堅強</座右銘>  
    </student2>  
</students>  
(2)解析過程
package cn.com.yy.dom4j;  
  
import java.io.File;  
import java.util.Iterator;  
import java.util.List;  
  
import org.dom4j.Attribute;  
import org.dom4j.Document;  
import org.dom4j.Element;  
import org.dom4j.io.SAXReader;  
import org.junit.Test;  
  
public class Dom4JforXML {  
      
    @Test  
    public void test() throws Exception{  
        //建立SAXReader物件  
        SAXReader reader = new SAXReader();  
        //讀取檔案 轉換成Document  
        Document document = reader.read(new File("src/cn/com/yy/dom4j/s.xml"));  
        //獲取根節點元素物件  
        Element root = document.getRootElement();  
        //遍歷  
        listNodes(root);  
    }  
      
    //遍歷當前節點下的所有節點  
    public void listNodes(Element node){  
        System.out.println("當前節點的名稱:" + node.getName());  
        //首先獲取當前節點的所有屬性節點  
        List<Attribute> list = node.attributes();  
        //遍歷屬性節點  
        for(Attribute attribute : list){  
            System.out.println("屬性"+attribute.getName() +":" + attribute.getValue());  
        }  
        //如果當前節點內容不為空,則輸出  
        if(!(node.getTextTrim().equals(""))){  
             System.out.println( node.getName() + ":" + node.getText());    
        }  
        //同時迭代當前節點下面的所有子節點  
        //使用遞迴  
        Iterator<Element> iterator = node.elementIterator();  
        while(iterator.hasNext()){  
            Element e = iterator.next();  
            listNodes(e);  
        }  
    }  
}  

(3)解析結果
當前節點的名稱:students  
當前節點的名稱:student1  
屬性id:001  
當前節點的名稱:微信公眾號  
微信公眾號:@殘缺的孤獨  
當前節點的名稱:學號  
學號:20140101  
當前節點的名稱:地址  
地址:北京海淀區  
當前節點的名稱:座右銘  
座右銘:要麼強大,要麼聽話  
當前節點的名稱:student2  
屬性id:002  
當前節點的名稱:新浪微博  
新浪微博:@殘缺的孤獨  
當前節點的名稱:學號  
學號:20140102  
當前節點的名稱:地址  
地址:北京朝陽區  
當前節點的名稱:座右銘  
座右銘:在哭泣中學會堅強  

4、dom4j操作節點屬性

使用dom4j可以操作節點屬性,比如新增節點屬性、刪除節點屬性、修改屬性值等操作。下面使用dom4j為上述的student1節點刪除id屬性,新添name屬性。

(1)程式碼示例

@Test  
    public void test2()throws Exception{  
        //建立SAXReader物件  
        SAXReader reader = new SAXReader();  
        //讀取檔案 轉換成Document  
        Document document = reader.read(new File("src/cn/com/yy/dom4j/s.xml"));  
        //獲取根節點元素物件  
        Element root = document.getRootElement();  
          
        System.out.println("-------新增屬性前------");  
        //獲取節點student1  
        Element student1Element = root.element("student1");  
        //遍歷  
        listNodes(student1Element);  
        //獲取其屬性  
        Attribute idAttribute = student1Element.attribute("id");  
        //刪除其屬性  
        student1Element.remove(idAttribute);  
        //為其新增新屬性  
        student1Element.addAttribute("name", "這是student1節點的新屬性");  
        System.out.println("-------新增屬性後------");  
        listNodes(student1Element);  
    }  
(2)結果

-------新增屬性前------  
當前節點的名稱:student1  
<span style="background-color: rgb(255, 0, 0);">屬性id:001</span>  
當前節點的名稱:微信公眾號  
微信公眾號:@殘缺的孤獨  
當前節點的名稱:學號  
學號:20140101  
當前節點的名稱:地址  
地址:北京海淀區  
當前節點的名稱:座右銘  
座右銘:要麼強大,要麼聽話  
-------新增屬性後------  
當前節點的名稱:student1  
<span style="background-color: rgb(255, 255, 255);"><span style="color:#ff0000;">屬性name:這是student1節點的新屬性  
</span></span>當前節點的名稱:微信公眾號  
微信公眾號:@殘缺的孤獨  
當前節點的名稱:學號  
學號:20140101  
當前節點的名稱:地址  
地址:北京海淀區  
當前節點的名稱:座右銘  
座右銘:要麼強大,要麼聽話

5、dom4j新增節點

使用dom4j可以刪除指定節點、新增節點等操作,我們使用dom4j為student1節點新增phone節點,如下。

(1)程式碼

//新增節點  
    @Test  
    public void test3()throws Exception{  
        //建立SAXReader物件  
        SAXReader reader = new SAXReader();  
        //讀取檔案 轉換成Document  
        Document document = reader.read(new File("src/cn/com/yy/dom4j/s.xml"));  
        //獲取根節點元素物件  
        Element root = document.getRootElement();  
        System.out.println("-------新增節點前------");  
        //獲取節點student1  
        Element student1Element = root.element("student1");  
        //遍歷  
        listNodes(student1Element);  
        //新增phone節點  
        Element phoneElement = student1Element.addElement("phone");  
        //為phone節點設定值  
        phoneElement.setText("137xxxxxxxx");  
        System.out.println("-------新增節點後------");  
        listNodes(student1Element);  
    }  

(2)結果
-------新增節點前------  
當前節點的名稱:student1  
屬性id:001  
當前節點的名稱:微信公眾號  
微信公眾號:@殘缺的孤獨  
當前節點的名稱:學號  
學號:20140101  
當前節點的名稱:地址  
地址:北京海淀區  
當前節點的名稱:座右銘  
座右銘:要麼強大,要麼聽話  
-------新增節點後------  
當前節點的名稱:student1  
屬性id:001  
當前節點的名稱:微信公眾號  
微信公眾號:@殘缺的孤獨  
當前節點的名稱:學號  
學號:20140101  
當前節點的名稱:地址  
地址:北京海淀區  
當前節點的名稱:座右銘  
座右銘:要麼強大,要麼聽話  
當前節點的名稱:phone  
<span style="color:#ff0000;">phone:137xxxxxxxx</span>  

6、把Document物件寫入新的檔案

有時,我們需要把document物件寫入新的檔案,dom4j提供了對應的API以便我們進行操作。我們在完成第 5 後,把document寫入新的檔案s1.xml,如下。

(1)程式碼

//新增節點後,寫入新的檔案  
    @Test  
    public void test4()throws Exception{  
        //建立SAXReader物件  
        SAXReader reader = new SAXReader();  
        //讀取檔案 轉換成Document  
        Document document = reader.read(new File("src/cn/com/yy/dom4j/s.xml"));  
        //獲取根節點元素物件  
        Element root = document.getRootElement();  
        System.out.println("-------新增節點前------");  
        //獲取節點student1  
        Element student1Element = root.element("student1");  
        //遍歷  
        listNodes(student1Element);  
        //新增phone節點  
        Element phoneElement = student1Element.addElement("phone");  
        //為phone節點設定值  
        phoneElement.setText("137xxxxxxxx");  
        System.out.println("-------新增節點後------");  
        listNodes(student1Element);  
        //把student1Element寫入新檔案  
        writerDocumentToNewFile(document);  
        System.out.println("---寫入完畢----");  
    }  
      
    //document寫入新的檔案  
    public void writerDocumentToNewFile(Document document)throws Exception{  
        //輸出格式  
        OutputFormat format = OutputFormat.createPrettyPrint();  
        //設定編碼  
        format.setEncoding("UTF-8");  
        //XMLWriter 指定輸出檔案以及格式  
        XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(new File("src/cn/com/yy/dom4j/s1.xml")),"UTF-8"), format);  
          
        //寫入新檔案  
        writer.write(document);  
        writer.flush();  
        writer.close();  
    }  

(2)檢視s1.xml檔案

<?xml version="1.0" encoding="UTF-8"?>  
  
<students>   
  <student1 id="001">   
    <微信公眾號>@殘缺的孤獨</微信公眾號>    
    <學號>20140101</學號>    
    <地址>北京海淀區</地址>    
    <座右銘>要麼強大,要麼聽話</座右銘>    
    <phone>137xxxxxxxx</phone>  
  </student1>    
  <student2 id="002">   
    <新浪微博>@殘缺的孤獨</新浪微博>    
    <學號>20140102</學號>    
    <地址>北京朝陽區</地址>    
    <座右銘>在哭泣中學會堅強</座右銘>   
  </student2>   
</students>  

因為涉及到中文,所以在輸出時要設定UTF8編碼,OutputStreamWriter進行設定編碼。

還有輸出格式的問題,在此處使用的是OutputFormat.createPrettyPrint(),輸出文件時進行了排版格式化。還有一種是OutputFormat.createCompactFormat()方法,輸出內容是一行,沒有進行格式化,是緊湊型的輸出。如下:

<?xml version="1.0" encoding="UTF-8"?>  
<students><student1 id="001"><微信公眾號>@殘缺的孤獨</微信公眾號><學號>20140101</學號><地址>北京海淀區</地址><座右銘>要麼強大,要麼聽話</座右銘><phone>137xxxxxxxx</phone></student1><student2 id="002"><新浪微博>@殘缺的孤獨</新浪微博><學號>20140102</學號><地址>北京朝陽區</地址><座右銘>在哭泣中學會堅強</座右銘></student2></students>