Node、Element、Document、Attribute...),面向接口編程,靈活性極高Node (根接口) ├── Attribute ├── Branch (可含子節點) │ ├── Document │ └── Element ├── CharacterData (標識基於字符的節點) │ ├── CDATA │ ├── Comment │ └── Text ├── DocumentType ├── Entity └── ProcessingInstruction
掌握此體系可避免 ClassCastException,如 Attribute 不能轉為 Element,Document 可轉為 Branch。
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("input.xml")); // 亦支持 InputStream, URL, Reader
Element root = doc.getRootElement();
// 遍歷所有子元素
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(); ) { ... }
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 等
}
}
}
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(),否則重複遍歷。
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());
// XML → String
String xml = document.asXML();
// String → XML
Document doc = DocumentHelper.parseText("James ");
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();
Document doc = DocumentHelper.createDocument();
Element root = doc.addElement("root");
Element author1 = root.addElement("author")
.addAttribute("name", "James")
.addAttribute("location", "UK")
.addText("James Strachan");
// 簡單輸出
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();
SAXReader 自動按聲明編碼解碼OutputFormat.setEncoding("UTF-8")(或 GBK/GB2312)五者統一,徹底杜絕亂碼。
實現 ElementHandler 接口,註冊到 SAXReader.addHandler("/path/to/element", handler),解析器遇到匹配元素回調 onStart/onEnd,處理完可 element.detach() 釋放內存,實現常駐內存處理超大 XML。