dom4j學習總結

原文:http://q.jobui.com/purejava/referUrl.php?url=6983.html&target=right

(一)創建Document的基本操作

/**
  * xml基本操作
  */

 public void BaseOperation(){
  //創建一個document
  Document document=DocumentHelper.createDocument();
  //創建根結點
  Element root=document.addElement("root");
  //爲根結點添加一個book節點
  Element book1=root.addElement("book");
  //爲book1添加屬性type
  book1.addAttribute("type","science");
  //爲book1添加name子節點
  Element name1=book1.addElement("Name");
  //並設置其name爲"Java"
  name1.setText("Java");
  //爲book1創建一個price節點,並設其價格爲100
  book1.addElement("price").setText("100");
  
  //爲根結點添加第二個book節點,並設置該book節點的type屬性
  Element book2=root.addElement("book").addAttribute("type","science");
  //爲book1添加name子節點
  Element name2=book2.addElement("Name");
  //並設置其name爲"Oracle"
  name2.setText("Oracle");
  //爲book1創建一個price節點,並設其價格爲200
  book2.addElement("price").setText("200");
  
  //輸出xml
  System.out.println(document.asXML());
 }

調用BaseOperation,輸出結果爲:

<?xml version="1.0" encoding="UTF-8"?>
<root>
 <book type="science">
  <Name>Java</Name>
  <price>100</price>
 </book>
 <book type="science">
  <Name>Oracle</Name>
  <price>200</price>
 </book>
</root>

(二)根據一個符合Document格式的字符串來生成一個Document

 /**將字符串轉化爲Document
  * @param str  輸入的字符串
  * @return  生成的document
  * @throws DocumentException
  */

 public Document parserStrtoDocument(String str) throws DocumentException{
  Document document=DocumentHelper.parseText(str);
  return document;
 }

調用示例:

String str="<root><book type='science'><Name>Java</Name><price>100</price></book></root>";

  Document document = parserStrtoDocument(str);
  System.out.println(document.asXML());

輸出結果爲:

<?xml version="1.0" encoding="UTF-8"?>
<root>
 <book type="science">
  <Name>Java</Name>
  <price>100</price>
 </book>
</root>

(三)取得xml節點屬性的基本方法

 /**
  * 取得xml的節點和屬性的值
  * @throws DocumentException
  */

 public void getBaseInfofromDocument() throws DocumentException{
  String str="<root><book type='science'><Name>Java</Name><price>100</price></book></root>";
  //生成一個Document
  Document document = DocumentHelper.parseText(str);
  //取得根結點
  Element root=document.getRootElement();
  //取得book節點
  Element book=root.element("book");
  //取得book節點的type屬性的值
  String type=book.attributeValue("type");
  //取得Name節點
  Element name=book.element("Name");
  //取得書名
  String bookname=name.getText();
  //取得書的價錢
  int price=Integer.parseInt(book.element("price").getText());
  
  //輸出書目信息
  System.out.println("書名:"+bookname);
  System.out.println("所屬類別:"+type);
  System.out.println("價格:"+price);
 }

調用getBaseInfofromDocument,輸出結果爲:

書名:Java
所屬類別:science
價格:100

(四)利用迭代,xpath取得節點及其屬性值

 /**利用迭代,xpath取得xml的節點及其屬性值
  * @throws DocumentException
  */

 public void getComplexInfofromDocument() throws DocumentException{


  String str="<root><book type='science'><Name>Java</Name><price>100</price></book>"
   +"<book type='science'><Name>Oracle</Name><price>120</price></book>"
   +"<book type='society'><Name>Society security</Name><price>130</price></book>"
   +"<author><name>chb</name></author></root>";
  //生成一個Document
  Document document = DocumentHelper.parseText(str);
  
  //提取類型爲"society"的書
  //此處需要添加支持xpath的jar包,詳細見備註
  Element society_book=(Element)document.selectSingleNode("/root/book[@type='society']");
  System.out.println(society_book.asXML());
  
  //提取價格節點的列表
  System.out.println("-----------價格列表-------------");
  List price=document.selectNodes("//price");
  for(int i=0;i<price.size();i++){
   Element elem_price=(Element)price.get(i);
   System.out.println(elem_price.getText());
  }
  
  //循環根結點下的所有節點,若當前節點爲book,則輸出這本書的詳細信息
  System.out.println("-------------書目詳情------------");
  System.out.println("書名/t/t類別/t/t價格");
  Element root=document.getRootElement();
  Iterator iterator=root.elementIterator();
  while(iterator.hasNext()){
   Element element=(Element)iterator.next();
   if(element.getName().equals("book")){
    System.out.print(element.element("Name").getText()+"/t");
    System.out.print(element.attributeValue("type")+"/t/t");
    System.out.print(element.element("price").getText()+"/n");
   }
  }

  //查找作者姓名
  Element author=(Element)document.selectSingleNode("//author");
  System.out.println("---------"+author.element("name").getText()+"----------");
  //提取作者的所有書目名稱
  Iterator iterator_book=root.elementIterator("book");  
  while(iterator_book.hasNext()){
   Element book=(Element)iterator_book.next();
   System.out.print(book.element("Name").getText()+"/t");
  }
  
  //屬性迭代
  System.out.println("/n-------屬性迭代--------");
  String str1="<book type='science' name='Java' price='100'/>";
  Document document1=DocumentHelper.parseText(str1);
  //開始迭代
  Iterator iterator_attribute=document1.getRootElement().attributeIterator();
  while(iterator_attribute.hasNext()){
   //提取當前屬性
   Attribute attribute=(Attribute)iterator_attribute.next();
   System.out.println(attribute.getName()+":"+attribute.getValue());
  }
 }

調用getComplexInfofromDocument,輸出結果爲:

<book type="society"><Name>Society security</Name><price>130</price></book>
-----------價格列表-------------
100
120
130
-------------書目詳情------------
書名  類別  價格
Java science  100
Oracle science  120
Society security society  130
---------chb----------
Java Oracle Society security 
-------屬性迭代--------
type:science
name:Java
price:100

備註:調用該方法之前,應該先向工程中添加支持xpath的jar包,否則,會出現以下錯誤:

java.lang.NoClassDefFoundError: org/jaxen/JaxenException
 at org.dom4j.DocumentFactory.createXPath(DocumentFactory.java:230)
 at org.dom4j.tree.AbstractNode.createXPath(AbstractNode.java:207)
 at org.dom4j.tree.AbstractNode.selectSingleNode(AbstractNode.java:183)
 at xml_chb.dom4j_chb.getComplexInfofromDocument(dom4j_chb.java:82)
 at xml_chb.dom4j_chb.main(dom4j_chb.java:92)
Exception in thread "main"

只需要引入jaxen包就行了,我使用的是hibernate包中的jaxen-1.1-beta-7.jar包。

 

刪除節點,屬性,合併兩個xml(下)

(一)移除節點及屬性

    /**移除節點和屬性的操作
     * 
@throws DocumentException
     
*/

    
public void RemoveOperator() throws DocumentException{
        
//待生成xml的字符串
        String str="<root><book type='science'><Name>Java</Name><price>100</price></book>"
            
+"<book type='society'><Name>Society security</Name><price>130</price></book>"
            
+"<author><name>chb</name><sex>boy</sex></author></root>";
        
//生成一個Document
        Document document = DocumentHelper.parseText(str);
        
        Element root
=document.getRootElement();
        
//刪除類型爲society的book節點
        Element book_society=(Element)document.selectSingleNode("//book[@type='society']");
        root.remove(book_society);
        System.out.println(
"1。正確的刪除了類型爲society的book節點");
        System.out.println(document.asXML());
        
        
//刪除sex節點
        Element sex=(Element)root.selectSingleNode("//sex");
        
        
//從root節點刪除
        root.remove(sex);
        System.out.println(
"2。這樣是不能刪除sex節點的");
        System.out.println(document.asXML());
        
        
//從author節點刪除
        root.element("author").remove(sex);
        System.out.println(
"3。這樣就可以正確刪除sex節點");
        System.out.println(document.asXML());
        
        
//刪除屬性
        Attribute type=root.element("book").attribute("type");
        root.element(
"book").remove(type);
        System.out.println(
"4。正確刪除book節點的type屬性");
        System.out.println(document.asXML());
    }

輸出結果爲:

1。正確的刪除了類型爲society的book節點
<?xml version="1.0" encoding="UTF-8"?>
<root><book type="science"><Name>Java</Name><price>100</price></book><author><name>chb</name><sex>boy</sex></author></root>
2。這樣是不能刪除sex節點的
<?xml version="1.0" encoding="UTF-8"?>
<root><book type="science"><Name>Java</Name><price>100</price></book><author><name>chb</name><sex>boy</sex></author></root>
3。這樣就可以正確刪除sex節點
<?xml version="1.0" encoding="UTF-8"?>
<root><book type="science"><Name>Java</Name><price>100</price></book><author><name>chb</name></author></root>
4。正確刪除book節點的type屬性
<?xml version="1.0" encoding="UTF-8"?>
<root><book><Name>Java</Name><price>100</price></book><author><name>chb</name></author></root>

分析:

第二個輸出結果不能刪除sex節點,我們需要看dom4j的API

remove

public boolean remove(Element element)
Removes the given Element if the node is an immediate child of this branch. If the given node is not an immediate child of this branch then the Node.detach()method should be used instead.

 

Parameters:
element - is the element to be removed
Returns:
true if the element was removed

從中我們可以看出,remove只能用在它自己的直接孩子節點上,不能用在孫子節點上,因爲sex節點不是root節點的直接孩子節點,所以不能刪除;而sex節點卻是author節點的直接孩子節點,所以第三個輸出可以刪除。

(二)將兩個Document合併爲一個Document

先看一個錯誤的情況

(1)使用add()方法添加

public void CombineDocument() throws DocumentException{
        
//待生成兩個Document的字符串
        String str_book="<root><book type='science'><Name>Java</Name><price>100</price></book>"
            
+"<book type='society'><Name>Society security</Name><price>130</price></book>"
            
+"</root>";
        String str_author
="<root><author><name>chb</name><sex>boy</sex></author></root>";
        
        
//生成兩個Document
        Document doc_book=DocumentHelper.parseText(str_book);
        Document doc_author
=DocumentHelper.parseText(str_author);
        
        
//取出doc_author的author節點,添加到doc_book的根結點
        Element author=(Element)doc_author.selectSingleNode("//author");
        doc_book.getRootElement().add(author);
        System.out.println(doc_book.asXML());
    }

調用CombineDocument函數,會出現以下錯誤:

org.dom4j.IllegalAddException: The node "org.dom4j.tree.DefaultElement@17bd6a1 [Element: <author attributes: []/>]" could not be added to the element "root" because: The Node already has an existing parent of "root"
 at org.dom4j.tree.AbstractElement.addNode(AbstractElement.java:1521)
 at org.dom4j.tree.AbstractElement.add(AbstractElement.java:1002)
 at xml_chb.dom4j_chb.CombineDocument(dom4j_chb.java:189)
 at xml_chb.dom4j_chb.main(dom4j_chb.java:199)
Exception in thread "main"

即提示author節點已經有一個root節點了,不能再添加到另一個節點上去。

(2)使用appendContent()方法

即將doc_book.getRootElement().add(author);

改爲:doc_book.getRootElement().appendContent(author);

輸出結果爲:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<book type="science"><Name>Java</Name><price>100</price></book>
<book type="society"><Name>Society security</Name><price>130</price></book>
<name>chb</name><sex>boy</sex>
</root>

可以看出,缺少了author節點,只是把author節點的子節點添加上去了,但是由此可見,appendContent方法是有希望的。

我們看一下dom4j的API:

appendContent

public void appendContent(Branch branch)
Appends the content of the given branch to this branch instance. This method behaves like the Collection.addAll(java.util.Collection) method.

 

Parameters:
branch - is the branch whose content will be added to me.

(3)使用正確的appendContent方法

將:Element author=(Element)doc_author.selectSingleNode("//author");

doc_book.getRootElement().appendContent(author);

改爲:doc_book.getRootElement().appendContent(doc_author.getRootElement());

輸出:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<book type="science"><Name>Java</Name><price>100</price></book>
<book type="society"><Name>Society security</Name><price>130</price></book>
<author><name>chb</name><sex>boy</sex></author>
</root>

是正確結果

 

(4)另一種可行的方法

public void CombineDocument() throws DocumentException{
        
//待生成兩個Document的字符串
        String str_book="<root><book type='science'><Name>Java</Name><price>100</price></book>"
            
+"<book type='society'><Name>Society security</Name><price>130</price></book>"
            
+"</root>";
        String str_author
="<root><author><name>chb</name><sex>boy</sex></author></root>";
        
        
//生成兩個Document
        Document doc_book=DocumentHelper.parseText(str_book);
        Document doc_author
=DocumentHelper.parseText(str_author);
        
        
//新生成一個Document
        Element author=DocumentHelper.createElement("author");
        author.appendContent((Element)doc_author.selectSingleNode(
"//author"));
        
//當前author尚無父節點,所以可以使用add方法添加
        doc_book.getRootElement().add(author);

        System.out.println(doc_book.asXML());
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章