随笔-6  评论-38  文章-40  trackbacks-0

 

本文主要讨论了用 dom4j 解析 XML 的基础问题,包括建立 XML 文档,添加、修改、删除节点,以及格式化(美化)输出和中文问题。可作为 dom4j 的入门资料。

 

1. 下载与安装

 

dom4j sourceforge.net 上的一个开源项目,主要用于对 XML 的解析。从 2001 7 月发布第一版以来,已陆续推出多个版本,目前最高版本为 1.5

dom4j 专门针对 Java 开发,使用起来非常简单、直观,在 Java 界, dom4j 正迅速普及。

 

可以到 http://sourceforge.net/projects/dom4j 下载其最新版。

 

dom4j1.5 的完整版大约 13M ,是一个名为 dom4j-1.5.zip 的压缩包,解压后有一个 dom4j-1.5.jar 文件,这就是应用时需要引入的类包,另外还有一个 jaxen-1.1-beta-4.jar 文件,一般也需要引入,否则执行时可能抛 java.lang.NoClassDefFoundError: org/jaxen/JaxenException 异常,其他的包可以选择用之。

 

2. 示例 XML 文档( holen.xml

 

为了述说方便,先看一个 XML 文档,之后的操作均以此文档为基础。

 

holen.xml

<?xml version="1.0" encoding="UTF-8"?>

<books>

       <!--This is a test for dom4j, holen, 2004.9.11-->

       <book show="yes">

              <title>Dom4j Tutorials</title>

       </book>

       <book show="yes">

              <title>Lucene Studing</title>

       </book>

       <book show="no">

              <title>Lucene in Action</title>

       </book>

       <owner>O'Reilly</owner>

</books>

 

这是一个很简单的 XML 文档,场景是一个网上书店,有很多书,每本书有两个属性,一个是书名 [title] ,一个为是否展示 [show] ,最后还有一项是这些书的拥有者 [owner] 信息。

 

3. 建立一个 XML 文档

 

 

    /**

      * 建立一个 XML 文档 , 文档名由输入属性决定

      * @param filename 需建立的文件名

      * @return 返回操作结果 , 0 表失败 , 1 表成功

      */

    public int createXMLFile(String filename){

       /** 返回操作结果 , 0 表失败 , 1 表成功 */

       int returnValue = 0;

       /** 建立 document 对象 */

       Document document = DocumentHelper.createDocument();

       /** 建立 XML 文档的根 books */

       Element booksElement = document.addElement( "books" );

       /** 加入一行注释 */

       booksElement.addComment( "This is a test for dom4j, holen, 2004.9.11" );

       /** 加入第一个 book 节点 */

       Element bookElement = booksElement.addElement( "book" );

       /** 加入 show 属性内容 */

       bookElement.addAttribute( "show" , "yes" );

       /** 加入 title 节点 */

       Element titleElement = bookElement.addElement( "title" );

       /** title 设置内容 */

       titleElement.setText( "Dom4j Tutorials" );

      

       /** 类似的完成后两个 book */

       bookElement = booksElement.addElement( "book" );

       bookElement.addAttribute( "show" , "yes" );

       titleElement = bookElement.addElement( "title" );

       titleElement.setText( "Lucene Studing" );

       bookElement = booksElement.addElement( "book" );

       bookElement.addAttribute( "show" , "no" );

       titleElement = bookElement.addElement( "title" );

       titleElement.setText( "Lucene in Action" );

      

       /** 加入 owner 节点 */

       Element ownerElement = booksElement.addElement( "owner" );

       ownerElement.setText( "O'Reilly" );

      

       try {

           /** document 中的内容写入文件中 */

           XMLWriter writer = new XMLWriter( new FileWriter( new File(filename)));

           writer.write(document);

           writer.close();

           /** 执行成功 , 需返回 1 */

           returnValue = 1;

       } catch (Exception ex){

           ex.printStackTrace();

       }

             

       return returnValue;

    }

 

说明:

Document document = DocumentHelper.createDocument();

通过这句定义一个 XML 文档对象。

 

Element booksElement = document.addElement("books");

通过这句定义一个 XML 元素,这里添加的是根节点。

Element 有几个重要的方法:

l         addComment :添加注释

l         addAttribute :添加属性

l         addElement :添加子元素

 

最后通过 XMLWriter 生成物理文件,默认生成的 XML 文件排版格式比较乱,可以通过 OutputFormat 类的 createCompactFormat() 方法或 createPrettyPrint() 方法格式化输出,默认采用 createCompactFormat() 方法,显示比较紧凑,这点将在后面详细谈到。

 

生成后的 holen.xml 文件内容如下:

 

 

<?xml version="1.0" encoding="UTF-8"?>

<books><!--This is a test for dom4j, holen, 2004.9.11--><book show="yes"><title>Dom4j Tutorials</title></book><book show="yes"><title>Lucene Studing</title></book><book show="no"><title>Lucene in Action</title></book><owner>O'Reilly</owner></books>

 

4. 修改 XML 文档

 

有三项修改任务,依次为:

l         如果 book 节点中 show 属性的内容为 yes, 则修改成 no

l         owner 项内容改为 Tshinghua ,并添加 date 节点

l         title 内容为 Dom4j Tutorials, 则删除该节点

 

 

    /**

      * 修改 XML 文件中内容 , 并另存为一个新文件

      * 重点掌握 dom4j 中如何添加节点 , 修改节点 , 删除节点

      * @param filename 修改对象文件

      * @param newfilename 修改后另存为该文件

      * @return 返回操作结果 , 0 表失败 , 1 表成功

      */

    public int ModiXMLFile(String filename,String newfilename){

       int returnValue = 0;

       try {

           SAXReader saxReader = new SAXReader();

           Document document = saxReader.read( new File(filename));

           /** 修改内容之一 : 如果 book 节点中 show 属性的内容为 yes, 则修改成 no */

           /** 先用 xpath 查找对象 */

           List list = document.selectNodes( "/books/book/@show" );

           Iterator iter = list.iterator();

           while (iter.hasNext()){

              Attribute attribute = (Attribute)iter.next();

              if (attribute.getValue().equals( "yes" )){

                  attribute.setValue( "no" );

              }   

           }

          

           /**

             * 修改内容之二 : owner 项内容改为 Tshinghua

             * 并在 owner 节点中加入 date 节点 ,date 节点的内容为 2004 - 09 - 11, 还为 date 节点添加一个属性 type

             */

           list = document.selectNodes( "/books/owner" );

           iter = list.iterator();

           if (iter.hasNext()){

              Element ownerElement = (Element)iter.next();

              ownerElement.setText( "Tshinghua" );

              Element dateElement = ownerElement.addElement( "date" );

              dateElement.setText( "2004-09-11" );

              dateElement.addAttribute( "type" , "Gregorian calendar" );

           }

          

           /** 修改内容之三 : title 内容为 Dom4j Tutorials, 则删除该节点 */

           list = document.selectNodes( "/books/book" );

           iter = list.iterator();

           while (iter.hasNext()){

              Element bookElement = (Element)iter.next();

              Iterator iterator = bookElement.elementIterator( "title" );

               while (iterator.hasNext()){

                  Element titleElement=(Element)iterator.next();

                  if (titleElement.getText().equals( "Dom4j Tutorials" )){

                     bookElement.remove(titleElement);

                  }

              }

           }          

          

           try {

              /** document 中的内容写入文件中 */

              XMLWriter writer = new XMLWriter( new FileWriter( new File(newfilename)));

              writer.write(document);

              writer.close();

              /** 执行成功 , 需返回 1 */

              returnValue = 1;

           } catch (Exception ex){

              ex.printStackTrace();

           }

          

       } catch (Exception ex){

           ex.printStackTrace();

       }

       return returnValue;

    }

   

 

说明:

List list = document.selectNodes("/books/book/@show" );

list = document.selectNodes("/books/book");

上述代码通过 xpath 查找到相应内容。

 

通过 setValue () setText () 修改节点内容。

 

通过 remove () 删除节点或属性。

 

5. 格式化输出和指定编码

 

默认的输出方式为紧凑方式,默认编码为 UTF-8 ,但对于我们的应用而言,一般都要用到中文,并且希望显示时按自动缩进的方式的显示,这就需用到 OutputFormat 类。

 

 

   

    /**

      * 格式化 XML 文档 , 并解决中文问题

      * @param filename

      * @return

      */

    public int formatXMLFile(String filename){

       int returnValue = 0;

       try {

           SAXReader saxReader = new SAXReader();

           Document document = saxReader.read( new File(filename));

           XMLWriter writer = null ;

           /** 格式化输出 , 类型 IE 浏览一样 */

           OutputFormat format = OutputFormat.createPrettyPrint();

           /** 指定 XML 编码 */

           format.setEncoding( "GBK" );

           writer= new XMLWriter( new FileWriter( new File(filename)),format);

           writer.write(document);

           writer.close();      

           /** 执行成功 , 需返回 1 */

           returnValue = 1;     

       } catch (Exception ex){

           ex.printStackTrace();

       }

       return returnValue;

    }

 

说明:

 

OutputFormat format = OutputFormat.createPrettyPrint();

这句指定了格式化的方式为缩进式,则非紧凑式。

 

format.setEncoding("GBK");

指定编码为 GBK

 

XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format);

这与前面两个方法相比,多加了一个 OutputFormat 对象,用于指定显示和编码方式。

 

6. 完整的类代码

 

前面提出的方法都是零散的,下面给出完整类代码。

 

Dom4jDemo.java

package com.holen.dom4j;

 

import java.io.File;

import java.io.FileWriter;

import java.util.Iterator;

import java.util.List;

 

import org.dom4j.Attribute;

import org.dom4j.Document;

import org.dom4j.DocumentHelper;

import org.dom4j.Element;

import org.dom4j.io.OutputFormat;

import org.dom4j.io.SAXReader;

import org.dom4j.io.XMLWriter;

 

/**

  * @author Holen Chen

  */

public class Dom4jDemo {

   

    public Dom4jDemo() {

    }

 

    public int createXMLFile(String filename){ …}

    public int ModiXMLFile(String filename,String newfilename){ …}

    public int formatXMLFile(String filename){ …}

 

    public static void main(String[] args) {

       Dom4jDemo temp = new Dom4jDemo();

       System.out.println(temp.createXMLFile( "d://holen.xml" ));         System.out.println(temp.ModiXMLFile( "d://holen.xml" , "d://holen2.xml" ));

       System.out.println(temp.formatXMLFile( "d://holen2.xml" ));

    }

}

 

说明:

main() 方法中依次调用三个方法,第一个方法用于生成 holen.xml ,第二个方法用于修改 holen.xml ,并且修改后的内容另存为 holen2.xml ,第三个方法将 holen2.xml 格式化缩进式输出,并指定编码方式为 GBK

 

重新格式化后 holen2.xml 文件显示如下:

 

项目视图供参考:

 

7. 总结

 

总的来说, dom4j 的使用是很简单的,而且与 Java 结合紧密,功能强大。

posted on 2006-11-30 18:48 一手的小窝窝 阅读(456) 评论(0)  编辑  收藏 所属分类: JAVA

只有注册用户登录后才能发表评论。


网站导航: