Chinaunix首页 | 论坛 | 博客
  • 博客访问: 152055
  • 博文数量: 15
  • 博客积分: 2061
  • 博客等级: 大尉
  • 技术积分: 395
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-06 14:25
文章分类

全部博文(15)

文章存档

2020年(1)

2012年(1)

2009年(7)

2008年(6)

我的朋友

分类: 系统运维

2008-07-06 19:22:59

一、DOM4J简介 

  DOM4J是dom4j.org出品的一个开源XML解析包,DOM4J最大的特色是使用大量的接口,这也是它被认为比JDOM灵活的主要原因。它的主要接口都在org.dom4j这个包里定义:

 Attribute  定义了XML属性
 Branch  Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为
 CDATA  定义了XML CDATA 区域
 CharacterData  CharacterData是一个标识借口,标识基于字符的节点。如CDATA,Comment, Text.
 Comment  Comment 定义了XML注释的行为
 Document  定义了XML文档
 DocumentType  DocumentType 定义XML DOCTYPE声明
 Element  Element定义XML 元素
 ElementHandler  ElementHandler定义了 Element 对象的处理器
 ElementPath  被 ElementHandler 使用,用于取得当前正在处理的路径层次信息
 Entity  Entity定义 XML entity
 Node  Node为所有的dom4j中XML节点定义了多态行为
 NodeFilter  NodeFilter 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate)
 ProcessingInstruction  ProcessingInstruction 定义 XML 处理指令.
 Text  Text 定义XML 文本节点.
 Visitor  Visitor 用于实现Visitor模式.
 XPath  XPath 在分析一个字符串后会提供一个XPath 表达式

接口之间的继承关系如下所示:

  • 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

二、使用示例

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结点

一切XML分析都是从Root元素开始的。

public Element getRootElement(Document doc){

       return doc.getRootElement();

    }

3。遍历XML树

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

1) 枚举(Iterator)

// 枚举所有子节点

    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

    }

2)递归

 public void treeWalk() {

       treeWalk(getRootElement());

    }

    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 { // do something....

           }

       }

}


 

3) Visitor模式

最令人兴奋的是DOM4JVisitor的支持,这样可以大大缩减代码量,并且清楚易懂。了解设计模式的人都知道,VisitorGOF设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为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不同的对象,将采用不同的方式来访问。上面是给出的ElementAttribute的简单实现,一般比较常用的就是这两个。VisitorSupportDOM4J提供的默认适配器,Visitor接口的Default Adapter模式,这个模式给出了各种visit(*)的空实现,以便简化代码。

    注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历子节点。我第一次用的时候,认为是需要自己遍历,便在递归中调用Visitor,结果可想而知。

4. XPath支持

    DOM4JXPath有良好的支持,如访问一个节点,可直接用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 = ...;

    String text = document.asXML();

// 字符串转XML

    String text = James ;

    Document document = DocumentHelper.parseText(text);



6. Styling a Document with XSLT
Applying XSLT on a Document is quite straightforward using the JAXP API from Sun. This allows you to work against any XSLT engine such as Xalan or SAXON. Here is an example of using JAXP to create a transformer and then applying it to a Document.

 

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;

import org.dom4j.Document;
import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;

public class Foo {

      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;
      }
}

阅读(1927) | 评论(2) | 转发(0) |
0

上一篇:XML分析工具的比较

下一篇:HTML转换xml

给主人留下些什么吧!~~

chinaunix网友2008-07-06 22:42:28

用DOM4J对XML文档的读写增删改等操作,是我自己的练习题,没有整理和注释,只做以后查看之用。主要方法在构造函数中做了简单说明,涉及到的XML、XSD、DTD文档不再写入。 package xml.dom4j.wkjava; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import

chinaunix网友2008-07-06 19:58:16

快速入门 使用迭代器(Iterators)   我们可以通过多种方法来操作XML文档,这些方法返回java里标准的迭代器(Iterators)。例如:   public void bar(Document document) throws DocumentException {   Element root = document.getRootElement();   //迭代根元素下面的所有子元素   for ( Iterator i = root.elementIterator(); i.hasNext(); ) {   Element element = (Element) i.next();   //处理代码   }   //迭代根元素下面名称为"foo"的子元素   for ( Iterator i = root.elementIterator( "foo" ); i.hasNext(); ) {   Element foo = (Element) i.next();   //处理代码   }   // 迭代根元素的属性attributes)