码迷,mamicode.com
首页 > 其他好文 > 详细

dom4j基础教程

时间:2015-05-13 12:03:13      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

转自 http://blog.csdn.net/whatlonelytear/article/details/42234937

Dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。

 

DOM4J使用起来非常简单。只要你了解基本的XML-DOM模型,就能使用。然而他自己带的指南只有短短一页(html),不过说的到挺全。国内的中文资料很少。

之前看过IBM developer社区的文章(参见附录),提到一些XML解析包的性能比较,其中DOM4J的性能非常出色,在多项测试中名列前茅。(事实上DOM4J的官方文档中也引用了这个比较)所以这次的项目中我采用了DOM4J作为XML解析工具。
在国内比较流行的是使用JDOM作为解析器,两者各擅其长,但DOM4J最大的特色是使用大量的接口,这也是它被认为比JDOM灵活的主要原因。

interface java.lang.Cloneable  
interface org.dom4j.Node    
interface org.dom4j.Attribute   
interface org.dom4j.Branch   
interface org.dom4j.Document   
interface org.dom4j.Element   
interface org.dom4j.CharacterData  
interface org.dom4j.CDATA   
interface org.dom4j.Comment   
interface org.dom4j.Text   
interface org.dom4j.DocumentType   
interface org.dom4j.Entity   
interface org.dom4j.ProcessingInstruction 

一目了然,很多事情都清楚了。大部分都是由Node继承来的。知道这些关系,将来写程序就不会出现ClassCastException了。
下面给出一些例子(部分摘自DOM4J自带的文档),简单说一下如何使用。

1. 读取并解析XML文档:

读写XML文档主要依赖于org.dom4j.io包,其中提供DOMReader和SAXReader两类不同方式,而调用方式是一样的。这就是依靠接口的好处。 

// 从文件读取XML,输入文件名,返回XML文档  
public Document read(String fileName) throws MalformedURLException, DocumentException {  
    SAXReader reader = new SAXReader();  
    Document document = reader.read(new File(fileName));  
    return document;  
}  

其中,reader的read方法是重载的,可以从  InputStream, File, Url 等多种不同的源来读取。得到的Document对象就带表了整个XML。
根据本人自己的经验,读取的字符编码是按照XML文件头定义的编码来转换。如果遇到乱码问题,注意要把各处的编码名称保持一致即可。

2. 取得Root节点
读取后的第二步,就是得到Root节点。熟悉XML的人都知道,一切XML分析都是从Root元素开始的。

public Element getRootElement(Document doc){  
    return doc.getRootElement();  
}  

3. 遍历XML树

DOM4J提供至少3种遍历节点的方法:

// 枚举所有子节点  
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {  
    Element element = (Element) i.next();  
    // do something  
}  
// 枚举名称为foo的节点  
for ( Iterator i = root.elementIterator(foo); i.hasNext();) {  
    Element foo = (Element) i.next();  
    // do something  
}  
// 枚举属性  
for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {  
    Attribute attribute = (Attribute) i.next();  
    // do something  
}  

3) Visitor模式
最令人兴奋的是DOM4J对Visitor的支持,这样可以大大缩减代码量,并且清楚易懂。了解设计模式的人都知道,Visitor是GOF设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为Visitor去访问许多Visitable。我们来看DOM4J中的Visitor模式(快速文档中没有提供)
只需要自定一个类实现Visitor接口即可。

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

调用: root.accept(new MyVisitor()) 

Visitor接口提供多种Visit()的重载,根据XML不同的对象,将采用不同的方式来访问。上面是给出的Element和Attribute的简单实现,一般比较常用的就是这两个。VisitorSupport是DOM4J提供的默认适配器,Visitor接口的Default Adapter模式,这个模式给出了各种visit(*)的空实现,以便简化代码。
注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历子节点。我第一次用的时候,认为是需要自己遍历,便在递归中调用Visitor,结果可想而知。

4. XPath支持

DOM4J对XPath有良好的支持,如访问一个节点,可直接用XPath选择。

public void bar(Document document) {  
List list = document.selectNodes( "//foo/bar" );  
Node node = document.selectSingleNode("//foo/bar/author");  
String name = node.valueOf( "@name ");  
}  

例如,如果你想查找XHTML文档中所有的超链接,下面的代码可以实现: 

public void findLinks(Document document) throws DocumentException {  
    List list = document.selectNodes( "//a/@href" );  
    for (Iterator iter = list.iterator(); iter.hasNext(); ) {  
        Attribute attribute = (Attribute) iter.next();  
        String url = attribute.getValue();  
    }  
}

5. 字符串与XML的转换

有时候经常要用到字符串转换为XML或反之, 
// XML转字符串 

Document document = null;  
String text = document.asXML();

// 字符串转XML

String text = "<person> <name>James</name> </person>";  
Document document = DocumentHelper.parseText(text);

6 用XSLT转换XML

public Document styleDocument(Document document,String stylesheet) throws Exception {  
    // load the transformer using JAXP  
    TransformerFactory factory = TransformerFactory.newInstance();  
    Transformer transformer = factory.newTransformer( new StreamSource( stylesheet ) ) ;  
    // now lets style the given document  
    DocumentSource source = new DocumentSource( document );  
    DocumentResult result = new DocumentResult();  
    transformer.transform( source, result );  
    // return the transformed document  
    Document transformedDoc = result.getDocument();  
    return transformedDoc;  
}  

7. 创建XML

一般创建XML是写文件前的工作,这就像StringBuffer一样容易。

public Document createDocument() {  
  Document document = DocumentHelper.createDocument();  
  Element root = document.addElement(root);  
  Element author1 =root.addElement(author).addAttribute(name, James).addAttribute(location, UK).addText(James Strachan);  
  Element author2 =root.addElement(author).addAttribute(name, Bob).addAttribute(location, US).addText(Bob McWhirter);  
  return document;  
}  

8. 文件输出

一个简单的输出方法是将一个Document或任何的Node通过write方法输出 

FileWriter out = new FileWriter( foo.xml );  
document.write(out);  
public void write(Document document) throws IOException {  
// 指定文件  
XMLWriter writer = new XMLWriter(new FileWriter( output.xml ));  
writer.write( document );  
writer.close();  
// 美化格式  
OutputFormat format = OutputFormat.createPrettyPrint();  
writer = new XMLWriter( System.out, format );  
writer.write( document );  
// 缩减格式  
format = OutputFormat.createCompactFormat();  
writer = new XMLWriter( System.out, format );  
writer.write( document );  
}

9.生成Document

/**  
 *   
 * dom4j生成与解析XML文档  
 *  
 * @author wanglp 2012-2-23  
 */    
public class Dom4jDemo {    
    
    /**  
     * 利用dom4j进行xml文档的写入操作  
     */    
    public void createXml(File file) {    
    
        // XML 声明 <?xml version="1.0" encoding="UTF-8"?> 自动添加到 XML文档中    
        // 使用DocumentHelper类创建文档实例(生成 XML文档节点的 dom4j API工厂类)    
        Document document = DocumentHelper.createDocument();    
        // 使用addElement()方法创建根元素 employees(用于向 XML 文档中增加元素)    
        Element root = document.addElement("employees");    
        // 在根元素中使用 addComment()方法添加注释"An XML Note"    
        root.addComment("An XML Note");    
        // 在根元素中使用 addProcessingInstruction()方法增加一个处理指令    
        root.addProcessingInstruction("target", "text");    
        // 在根元素中使用 addElement()方法增加employee元素。    
        Element empElem = root.addElement("employee");    
        // 使用 addAttribute()方法向employee元素添加id和name属性    
        empElem.addAttribute("id", "0001");    
        empElem.addAttribute("name", "wanglp");    
        // 向employee元素中添加sex元素    
        Element sexElem = empElem.addElement("sex");    
        // 使用setText()方法设置sex元素的文本    
        sexElem.setText("m");    
        // 在employee元素中增加age元素 并设置该元素的文本。    
        Element ageElem = empElem.addElement("age");    
        ageElem.setText("25");    
        // 在根元素中使用 addElement()方法增加employee元素。    
        Element emp2Elem = root.addElement("employee");    
        // 使用 addAttribute()方法向employee元素添加id和name属性    
        emp2Elem.addAttribute("id", "0002");    
        emp2Elem.addAttribute("name", "fox");    
        // 向employee元素中添加sex元素    
        Element sex2Elem = emp2Elem.addElement("sex");    
        // 使用setText()方法设置sex元素的文本    
        sex2Elem.setText("f");    
        // 在employee元素中增加age元素 并设置该元素的文本。    
        Element age2Elem = emp2Elem.addElement("age");    
        age2Elem.setText("24");    
        // 可以使用 addDocType()方法添加文档类型说明。    
        // document.addDocType("employees", null, "file://E:/Dtds/dom4j.dtd");    
        // 这样就向 XML 文档中增加文档类型说明:    
        // <!DOCTYPE employees SYSTEM "file://E:/Dtds/dom4j.dtd">    
        // 如果文档要使用文档类型定义(DTD)文档验证则必须有 Doctype。   
        try {    
            XMLWriter output = new XMLWriter(new FileWriter(file));    
            output.write(document);    
            output.close();    
        } catch (IOException e) {    
            System.out.println(e.getMessage());    
        }    
    }    
    
    /**  
     * 利用dom4j进行xml文档的读取操作  
     */    
    public void parserXml(File file) {    
    
        Document document = null;    
        // 使用 SAXReader 解析 XML 文档 catalog.xml:    
        SAXReader saxReader = new SAXReader();    
        try {    
            document = saxReader.read(file);    
        } catch (DocumentException e) {    
            e.printStackTrace();    
        }    
        // 将字符串转为XML    
        // document = DocumentHelper.parseText(fileString);   
        // 获取根节点    
        Element root = document.getRootElement();    
        // 打印节点名称    
        System.out.println("<" + root.getName() + ">");    
        // 获取根节点下的子节点遍历    
        Iterator<?> iter = root.elementIterator("employee");    
        // 遍历employee节点    
        while (iter.hasNext()) {    
            // 获取当前子节点    
            Element empEle = (Element) iter.next();    
            System.out.println("<" + empEle.getName() + ">");    
            // 获取当前子节点的属性遍历    
            Iterator<?> attrList = empEle.attributeIterator();    
            while (attrList.hasNext()) {    
                Attribute attr = (Attribute) attrList.next();    
                System.out.println(attr.getName() + "=" + attr.getValue());    
            }    
            // 遍历employee节点下所有子节点    
            Iterator<?> eleIte = empEle.elementIterator();    
            while (eleIte.hasNext()) {    
                Element ele = (Element) eleIte.next();    
                System.out.println("<" + ele.getName() + ">" + ele.getTextTrim());    
            }    
            // 获取employee节点下的子节点sex值    
            // String sex = empEle.elementTextTrim("sex");    
            // System.out.println("sex:" + sex);    
        }    
        System.out.println("</" + root.getName() + ">");    
    }    
    
    public static void main(String[] args) {    
        Dom4jDemo dom4j = new Dom4jDemo();    
        File file = new File("e:/dom4j.xml");    
        // dom4j.createXml(file);    
        dom4j.parserXml(file);    
    }    
}

如何,DOM4J够简单吧,当然,还有一些复杂的应用没有提到,如ElementHandler等。如果你动心了,那就一起来用DOM4J.

dom4j基础教程

标签:

原文地址:http://www.cnblogs.com/whatlonelytear/p/4499652.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!