本文主要讲述的是Dom4j在把Document保存到文件过程中出现的一个中文问题,文中不足之处欢迎大家批评指教。
  Dom4j是一个比较优秀的java开源xml解析项目,支持DOM, SAX and JAXP.,并提供对XPath查询语言的强大支持。因此,在EasyJF团队的很多开源项目中,如EasyJWeb、EasyDBO等都是使用Dom4j来处理xml文件相关操作。
 
1、从一个xml文件中载入一个Dom到内存:
  FileInputStream in = new FileInputStream(new File(fileName));
  SAXReader reader = new SAXReader();
  doc = reader.read(in);
2、把Dom中的数据写入到xml文件中
  使用Dom4j,要把一个Dom中的数据写入到文件非常简单,API如下:
   public void write(Writer writer) throws IOException;
  因此,假如我们要把一个Document写入到c:\test.xml文件中,可以简单的使用下面的代码即可:
        java.io.Writer wr= new java.io.FileWrite(filename);
  doc.write(wr);
        wr.close();//注意,必须要执行close()方法,才会实现真正的写入
  
  这种用法也是Dom4j所推荐我们使用的非常简单的方法。然而,当我们的dom中包含有中文字符数据的时候,这种方法写入的xml文档却无法使直觉打开。会提示类似如下的错误:
   org.dom4j.DocumentException: invalid byte 1 of 1-byte UTF-8 sequence (0xb2) Nested exception: invalid byte 1 of 1-byte UTF-8 sequence (0xb2)
 at org.dom4j.io.SAXReader.read(SAXReader.java:484)
 at org.dom4j.io.SAXReader.read(SAXReader.java:343)
 at 
  我们可以看生成的xml文件编码,内容是utf-8的,但文件格式确是ANSI的,如下图所示:

 
原因分析:
  由于FileWriter默认的输出编码是ANSI编码,而Dom4j中的wirte方法提供的内容实际是以UTF-8保存的,因此造成了包括中文字符的XML文件无法正常阅读。
 
解决方法:
   不能使用简单的FileWriter,而应该是使用一个能指定具体输出编码的Writer,在JDK的io包中, OutputStreamWriter可以指定输出编码。
  正确的代码如下:
    java.io.OutputStream out=new java.io.FileOutputStream(fileName);
   java.io.Writer wr=new java.io.OutputStreamWriter(out,"UTF-8");   
   doc.write(wr);   
   wr.close();
   out.close();

  简化一下可以写成下面的样式:

   java.io.Writer wr=new java.io.OutputStreamWriter(new java.io.FileOutputStream(fileName),"UTF-8");   
   doc.write(wr);   
   wr.close();

小结:
  由于大多数优秀的基础性开源项目都是老外开发,他们不大可能在中文平台下进行测试,用例数据也很少会使用中文平台,因此,我们即使按照这些开源项目的通用说明文档及用户指南去操作,也会出现很多不可预知的错误。这也是为什么本人要参与组建开源团队EasyJF,提倡搞国产开源,并开发一些基础性的开源框架如EasyJWeb、EasyDBO的一个初衷。
  当然,这里提出的中文问题,算是一个还“没来得及商量”以及要通过一些罕见的处理才能正确运行的中文问题。因此,同样归并到了“中文问题没商量”系列中。

(注:本文作者,EasyJF开源团队 大峡,转载请保留作者声明!)