使用DOM4J遍歷文檔

jjui 9年前發布 | 63K 次閱讀 Dom4j XML操作類庫

dom4j提供了幾種不同的選項用于遍歷Document對象和它的子對象。

Iterator,Lists和Index-Based Access

例如,輸出Element所有子元素location屬性的屬性值:

public void outputLocationAttributes(Element parent) {
    for(Iterator it = parent.elementIterator(); it.hasNext();){
        Element child = (Element) it.next();
        String value = child.attributeValue("location");
        if(value == null){
            System.out.println("No location attribute");
        }else{
            System.out.println("Location attribute value is " + value);
        }
    }
}


注意在這個例子中,我使用了elementIterator()方法,此工具方法返回List列表的一個java.util.Iterator,該list列表是由elements()方法返回的。如果你不想用Iterator接口,想使用基于索引的訪問,那么你可以使用nodeCount()和node()方法:

public void outputLocationAttributes2(Element parent) {
    for(int i=0;i<parent.nodeCount();i++){
        Node node = parent.node(i);
        if(node instanceof Element) {
            Element child = (Element) node;
            String value = child.attributeValue("location");
            if(value == null) {
                System.out.println("NO location attribute");
            }else{
                System.out.println("Location attribute value is " + value);
            }
        }
    }
}


XPath

dom4j有一個XPath接口,該對象由DocumentFactory中的createXPath()方法或DocumentHelper中的createXPath()方法創建。dom4j的XPath接口獨特之處在于:它可以通過XPath表達式對結果列表進行排序,不管是Node對象的列表(sort方法),還是一個表達式的結果(有兩三個參數的selectNodes()方法)

示例,見下面xml文檔:

<?xml version='1.0" encoding="UTF-8"?>
<books>
    <book>
        <title>Java &amp; XML</title>
        <pubDate>2006</pubDate>
    </book>
    <book>
        <title>Learning UML</title>
        <pubDate>2003</pubDate>
    </book>
    <book>
        <title>XML in a Nutshell</title>
        <pubDate>2004</pubDate>
    </book>
    <book>
        <title>Apache cookbook</title>
        <pubDate>2003</pubDate>
    </book>
</books>


如果你想根據出版日期將書名列表進行排序,你可以創建兩個單獨的XPath表達式,來獲取book元素,并對它們一一進行排序,然后像這樣使用它們,如下所示:

package javaxml3;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org. dom4j.DocumentHelper;
import org.dom4j.Element;
import org. dom4j.XPath;
import org.dom4j.io.SAXReader;

public class SortingXPath{
    public static void main(String[] args) throws Exception {
        Document doc = new SAXReader().read(new File("books.xml"));
        XPath bookPath = DocumentHelper.createXPath("http://book");
        XPath sortPath = DocumentHelper.createXPath("pubDate");
        List books = bookPath.selectNodes(doc,sortPath);  //sortPath是用于排序的XPath
        for(Interator it = books.iterator();it.hasNext();){
            Element book = (Element) it.next();
            System.out.println(book.elementText("title");
        }
    }
}


這是按照書名升序輸出的,從Learning UML開始,直至Java & XML結尾。這里并不有提供按降序排列的機制。相反,你可以使用Java.util.Collections類的reverse()靜態方法轉換順序。帶三個參數的selectNodes()方法刪除了結果列表中出現重復值的Node對象(第三個參數是true,如果是false的話,重復的Node對象就不會被刪除),如果調用它篩選上面例子中的節點,代碼可以寫成這樣:

List books = bookPath.selectNodes(doc,sortPath,true);


這樣就只輸出三個書名,Apache Cookbook將會排除在外,因為它和Learnig UML的出版日期相同。

除XPath類之外,Node接口有一些方法,你可以簡單的傳入String給其中的一個方法來計算XPath表達式的值。Node接口的XPath特定方法如下:

public interface Node{
    List selectNodes(String xpathExpression);
    Object selectObject(String xpathExpression);
    List selectNodes(String xpathExpression,String comparisonXPathExpression);
    List selectNodes(String xpathExpression,String comparisonXPathExpression,boolean removeDuplicates);
    Node selectSingleNode(String xpathExpression);
    String valueOf(String xpathExpression);
    Number numberValueOf(String xpathExpression);
    boolean matches(String xpathExpression);
}


對于后臺實現而言,一般會使用XPath類求表達式的值,然后傳遞給這些方法。因為這些方法處理String,一般情況下,每次調用這類方法都將會創建一個新的XPath對象。因此,如果你想對一個相同的XPath表達式進行重復求值,XPath類提供了一個較好的方式,這樣就只對你的表達式進行一次編譯。此外,這些方法不能處理命名空間,變量,或自定義函數,如果這些功能是必要的,XPath類是你唯一的選擇。但是,這并不意味著這些方法是無用的。實際上,它們使用起來非常方便,并且代碼量很小。

還有一些Node接口中的方法很值得一提。比如說,getPath()方法getUniquePath()方法返回一個XPath表達式這個表達式是用來求節點列表中的值,其中包含了當前的節點。getUniquePath()方法比getPath()方法更進了一步,它添加了索引,以確保XPath表達式只對這一節點求值。除了不帶參數的方法外,getPath()方法和getUniquePath()方法都重載了,并接收一個ELement元素,在這種情況下,將會產生一個相對的XPath表達式,從一個傳遞的ELement到當前的節點。

 本文由用戶 jjui 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!