首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Dom4j 核心用法深度解析:接口體系、遍歷三式、XPath、輸出格式化與中文編碼

     編輯:Java 相關知識

Dom4j 核心優勢

  • 基於 Java Collection Framework 設計,API 符合 Java 慣用模式
  • 大量使用接口(Node、Element、Document、Attribute...),面向接口編程,靈活性極高
  • 完整支持 DOM、SAX、JAXP,可無縫切換解析器
  • 內置 XPath 引擎(Jaxen),查詢表達力強
  • 性能優異,多項基準測試領先於 JDOM、XOM 等同類庫

核心接口繼承圖

Node (根接口)
├── Attribute
├── Branch (可含子節點)
│   ├── Document
│   └── Element
├── CharacterData (標識基於字符的節點)
│   ├── CDATA
│   ├── Comment
│   └── Text
├── DocumentType
├── Entity
└── ProcessingInstruction

掌握此體系可避免 ClassCastException,如 Attribute 不能轉為 Element,Document 可轉為 Branch。

核心操作速查

1. 讀取 XML → Document

SAXReader reader = new SAXReader();
Document doc = reader.read(new File("input.xml")); // 亦支持 InputStream, URL, Reader

2. 獲取根元素

Element root = doc.getRootElement();

3. 三種遍歷方式

① 迭代器(最常用)

// 遍歷所有子元素
for (Iterator it = root.elementIterator(); it.hasNext(); ) {
    Element el = it.next();
    // ...
}
// 遍歷指定名稱元素
for (Iterator it = root.elementIterator("foo"); it.hasNext(); ) { ... }
// 遍歷屬性
for (Iterator it = root.attributeIterator(); it.hasNext(); ) { ... }

② 遞歸(配合 node API)

public void treeWalk(Element element) {
    for (int i = 0, n = element.nodeCount(); i < n; i++) {
        Node node = element.node(i);
        if (node instanceof Element) {
            treeWalk((Element) node);
        } else {
            // 處理 Text, Comment, CDATA 等
        }
    }
}

③ Visitor 模式(最優雅)

public class MyVisitor extends VisitorSupport {
    public void visit(Element el) { System.out.println("Element: " + el.getName()); }
    public void visit(Attribute attr) { System.out.println("Attribute: " + attr.getName()); }
}

// 調用:自動遍歷整棵樹
root.accept(new MyVisitor());

注意:accept() 會自動遞歸遍歷所有子孫節點,不要在遞歸中再次調用 accept(),否則重複遍歷。

4. XPath 查詢

List list = doc.selectNodes("//foo/bar");
Node node = doc.selectSingleNode("//foo/bar/author");
String name = node.valueOf("@name"); // 直接取屬性值,自動處理 null

// 實例:提取所有超鏈接
List links = doc.selectNodes("//a/@href");
for (Attribute href : links) System.out.println(href.getValue());

5. 字符串 ⇄ XML 雙向轉換

// XML → String
String xml = document.asXML();

// String → XML
Document doc = DocumentHelper.parseText("James");

6. XSLT 轉換

TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(stylesheet));
DocumentSource source = new DocumentSource(document);
DocumentResult result = new DocumentResult();
transformer.transform(source, result);
Document transformed = result.getDocument();

7. 構建 XML(鏈式 API)

Document doc = DocumentHelper.createDocument();
Element root = doc.addElement("root");
Element author1 = root.addElement("author")
    .addAttribute("name", "James")
    .addAttribute("location", "UK")
    .addText("James Strachan");

8. 文件輸出與格式化

// 簡單輸出
document.write(new FileWriter("out.xml"));

// 格式化輸出
OutputFormat format = OutputFormat.createPrettyPrint(); // 縮進美化
format.setEncoding("GBK"); // 必須設置編碼,否則中文亂碼
XMLWriter writer = new XMLWriter(new FileWriter("out.xml"), format);
writer.write(document);
writer.close();

中文編碼問題終極方案

  1. Java 源文件編碼 = UTF-8(IDE 設置)
  2. XML 文件聲明
  3. 讀取時:SAXReader 自動按聲明編碼解碼
  4. 寫入時:OutputFormat.setEncoding("UTF-8")(或 GBK/GB2312)
  5. 控制台/日志輸出編碼與文件一致

五者統一,徹底杜絕亂碼。

進階主題:ElementHandler 流式處理大文件

實現 ElementHandler 接口,註冊到 SAXReader.addHandler("/path/to/element", handler),解析器遇到匹配元素回調 onStart/onEnd,處理完可 element.detach() 釋放內存,實現常駐內存處理超大 XML。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved