dom4j的一般应用
dom4j的官方地址:http://www.dom4j.org
dom4j是一个成功的开源项目,从java的对象概念的角度出发,按照通常的使用规范来处理xml文档,可以说,在java社区里,dom4j使用的最为广泛了,以下是如,众所周知的o/r mapping工具hibernate就是使用dom4j来解释xml文档的(ejb3.0就是基于hibernate实现的),由此可见,dom4j的使用广泛之处。dom4j的一个最大的实用之处是支持XPath表达式的查询,这样,我们可以在dom4j的Document结构中使用这种简单的表达式就可以快速找到我们需要的某个元素了。
package com.gdapp.oa.app; import org.dom4j.*; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.util.Iterator; /** * 对dom4j的操作,添加,修改,显示 * * @author bicashy */ public class Dom4jAPP { public static void main(String[] args) { Dom4jAPP app = new Dom4jAPP(); app.writeXML("e:/bicashy.xml"); app.displayXML("e:/bicashy.xml"); //app.modifyXML("e:/bicashy.xml"); } /** * 写XML文件 * * @param path */ public void writeXML(String path) { try { FileWriter out = new FileWriter(path); Document doc = createDocument(); write(doc, path); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 返回Document对象 * * @param path * @return */ public Document readXML(String path) { Document doc = null; try { SAXReader reader = new SAXReader(); doc = reader.read(path); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } return doc; } //修改xml文件(将“child”节点的属性“姓名”的值改为 “金刚”,将内容改为“我是谁?”) public void displayXML(String path) { Document doc = readXML(path); Element root = doc.getRootElement(); for (Iterator it = root.elementIterator(); it.hasNext(); ) { Element e = (Element) it.next(); System.out.println("【内容==" + e.getText() + "】【 enjoy属性==" + e.attributeValue("enjoy") + "】"); } //枚举名称为"bicashy"的节点 for (Iterator i = root.elementIterator("bicashy"); i.hasNext(); ) { Element foo = (Element) i.next(); System.out.println("【内容==" + foo.getText() + "】【 enjoy属性==" + foo.attributeValue("enjoy") + "】"); } // 枚举"bicashy"节点下的属性 Element bicashy = root.element("bicashy"); for (Iterator i = bicashy.attributeIterator(); i.hasNext(); ) { Attribute attribute = (Attribute) i.next(); System.out.println("属性" + attribute.getName() + "==" + attribute.getText()); } //枚举"child"节点下的属性 Element child = root.element("parent").element("child"); for (Iterator i = child.attributeIterator(); i.hasNext(); ) { Attribute attribute = (Attribute) i.next(); System.out.println("属性" + attribute.getName() + "==" + attribute.getText()); } } //递归 public void modifyXML(String path) { try { SAXReader reader = new SAXReader(); Document doc = reader.read(path); Element root = doc.getRootElement(); Element child = root.element("parent").element("child"); for (Iterator i = child.attributeIterator(); i.hasNext(); ) { Attribute attribute = (Attribute) i.next(); if (attribute.getName().equals("姓名")) { attribute.setText("金刚"); } } child.setText("我是谁?"); write(doc, path); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void treeWalk(String path) { Document doc = readXML(path); Element root = doc.getRootElement(); treeWalk(root); } public void treeWalk(Element element) { for (int i = 0, size = element.nodeCount(); i < size; i++) { Node node = element.node(i); if (node instanceof Element) { treeWalk((Element) node); } else { System.out.println("##" + "==" + node.getText()); } } } /* Best of youIII killWHO AM I? */ /** * 写入文件 * * @param doc 文档对象 * @param outpath 文件路径 */ public void write(Document doc, String outpath) { XMLWriter writer = null; try { writer = new XMLWriter(new FileOutputStream(new File(outpath))); writer.write(doc); writer.close(); //美化格式(优美格式) OutputFormat format = OutputFormat.createPrettyPrint();// 定义文档的格式为美化型(pretty) format.setEncoding("GBK");// 格式编码为“gbk” writer = new XMLWriter(System.out, format); writer.write(doc); //缩进格式 // format = OutputFormat.createCompactFormat(); // writer = new XMLWriter(System.out,format); // writer.write(doc); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Document createDocument() { Document document = DocumentHelper.createDocument(); Element root = document.addElement("root"); Element bicashy1 = root.addElement("bicashy") .addAttribute("name", "wangpengfei") .addAttribute("sex", "male") .addAttribute("enjoy", "computer") .addText("Best of you"); Element bicashy2 = root.addElement("ladybird") .addAttribute("name", "dibowey") .addAttribute("sex", "male") .addAttribute("enjoy", "muder") .addText("III kill"); Element bicashy3 = root.addElement("parent"); Element bicashy4 = bicashy3.addElement("child") .addAttribute("姓名", "毛孩") .addAttribute("乳名", "小屁孩") .addText("WHO AM I?"); return document; } }
dom4j是基于面向接口的样式来实现处理xml文档的,这种方法在面向对象的领域里特别常见。使用的常用接口都封装在org.dom4j包里,而怎样读取xml文档呢?则是使用一系列的api函数,这些常用方法都封装在org.dom4j.io。
(1)从面向对象的角度来看,dom4j对XML的文档结构进行了封装,从一个文档的角度来说(我们不考虑内存中的数据结构的话),可以简单的把一个XML文档就当做一个org.dom4j.Document:
我们现在使用dom4j的Document结构,而不是使用w3c的Document结构,读取一个文件,在内存中构造一个Document结构:Document doc=new SAXReader().read(new File("...")); 就可以获得一个Document结构。注意,dom4j同时也对w3c的Document结构,SAX Event的支持,具体的使用可以参看docs/cookbook.html中的内容。这里不一一介绍。
(2)获得一个dom4j的Document结构之后,从面向对象的角度,我们自然而然的想起的是XML中的element,dom4j根据这种想法对这些进行了封装org.dom4j.Element类就是对这些进行了封装,从Document中获得Element:
首先获得一个root元素,Element root=doc.getRootElement();而其他的元素也可以根据这个root元素来获得。
(4)一个元素的属性的话,则是Attribute,在Element类中,有非常容易操作的方法添加于获得Attribute,addAttritue();attribute()等函数原型都提供了操作。
(5)dom4j同时也提供了在内存中的数据结构的构造,不降低处理的灵活性。如:Node就是对一个xml文档树的节点的封装,而Branch则是对一个树的分支的封装,通过使用这些,可以灵活的按照树的结构来处理xml文档。敏感的朋友可能会注意到,Document和Element都是Node与Branch的子类,这种不同功能的领域的封装可以按照对象的处理与数据结构的结合,灵活的处理xml文档。