用Dom4j解析XML及中文问题[转]

来源:互联网 发布:js高级程序设计 编辑:程序博客网 时间:2024/04/29 22:07

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

 

1. 下载与安装

 

dom4jsourceforge.net上的一个开源项目,主要用于对XML的解析。从20017月发布第一版以来,已陆续推出多个版本,目前最高版本为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结合紧密,功能强大。

 

参考资料

 

1.  dom4j文档

2.  使用 dom4j 解析 XMLDeepak VohradeveloperWorks

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小宝宝有四个月了母乳不够吃怎么办 一个月的宝宝吐奶厉害怎么办 新生儿吐奶吐一次吐的特别多怎么办 把孩子打了一次现在说话结巴怎么办 宝宝五岁了口吃越来越严重了怎么办 幼儿把自己的舌头扣破皮了怎么办 6岁宝贝烧到39度怎么办 2岁半的宝宝说话结巴怎么办 2周3宝宝不会说话胆小怎么办 宝宝我2岁多了说话有点结巴怎么办 两岁宝宝说话突然结巴了怎么办 两岁3宝宝叫她名字不理人怎么办 九个月的宝宝身高不达标怎么办 3岁宝宝又吐又拉怎么办 宝宝发烧39度怎么办手脚很烫 两岁宝宝吃什么吐什么怎么办 7岁宝宝吃多了吐怎么办 7个月的宝宝大便干燥怎么办 10个月宝宝便秘大便干燥怎么办 一岁半宝宝老是拉糊糊状大便怎么办 外阴部长了一个疙瘩有点痒怎么办 小孩打架被另一个小孩家人告怎么办 德保豆浆机有电但不工作怎么办 刚买的笔记本c盘不足怎么办 qq糖粘在喉咙气管里怎么办 穿上旗袍后感觉后腰处不平整怎么办 机打票给客人给错联怎么办?急 ps修证件照感觉不太立体怎么办 手机百度上下载的文档打不开怎么办 5岁宝宝乘飞机没带证件怎么办 网上订飞机票忘记订儿童票了怎么办 两岁宝宝对牛奶鸡蛋过敏了怎么办 两岁宝宝坐不住好跑怎么办 宝宝两岁多了不愿意坐小马桶怎么办 坐火车小孩拉屎在被子上怎么办 川航飞机票名字错了一个字怎么办 胜战本领怎么看走向战场怎么办 数数字油画你的颜料干了怎么办? 数字油画涂颜料涂错了怎么办 绝地求生模拟器注册已达上限怎么办 孕妇把番茄和虾一起吃了怎么办