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所推荐使用的非常简单的方法。
也可以用以下代码来修改保存xml文件:
File file = new File("D:/Workspaces for MyEclipse 7.1/test/src/com/config/DemoPkgrptb.xml");
SAXReader reader = new SAXReader();
Document doc = reader.read(file);
List list;
Iterator itr;
/*
* 设置汇总表
*/
list = doc.selectNodes("//Parameter[@Name='Query']");
itr = list.iterator();
while(itr.hasNext()){
Element elt = (Element) itr.next();
elt.attribute("Value").setValue(etlSumTable);
}
XMLWriter writer = new XMLWriter(new FileWriter(file));
writer.write(doc);
writer.close();
然而,当文件中包含有中文字符数据的时候,这种方法生成或保存过的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)
原因分析:
用FileWriter默认的输出编码是与操作系统默认文件编码一致,在中文widows中是ANSI编码,java中由Writer类继承下来的子类没有提供编码格式处理,而Dom4j中的wirte方法(例如,API方法:write(Document doc))默认是以utf-8格式来保存的,因此文件中的内容是utf-8编码格式,而文件本身却是以ANSI编码保存的。当在myeclipse中打开xml文件时,xml中的中文字符就显示为乱码,当再次运行程序做xml文件修改操作时,解析就出错,出现上面的错误提示。
出现上面的编码问题是因为使用了org.dom4j.io.XMLWriter的构造函数:XMLWriter(Writer writer) ,真正元凶是构造函数的参数Writer类的子类(如:FileWriter)不提供编码格式处理,将文件保存为何系统一致的ANSI编码。
解决方法:
通过org.dom4j.io.XMLWriter的构造函数:XMLWriter(OutputStream out) 来构建xml文档,将上面的代码修改如下:
XMLWriter writer = new XMLWriter(new FileOutputStream(file));
writer.write(doc);
writer.close();
这样,文件将以utf-8编码格式保存,中文也能正常显示和解析了。