Dom4j的asXML()自动编码的解决办法
在使用Dom4j的时候,有时候需要将一个Document对象转换为一个String,可以直接调用Document.asXML()方法来实现。可是调用这个方法的结果是:生成的字符串按照UTF-8进行了重新编码。这样,如果之前你的xml编码为GBK,那么你的调用此方法后,编码就变为UTF-8了,输出的中文字符就发生乱码。
有什么解决方案呢,在网上找了很久,也没找到原因。最后经过翻阅Dom4j的API文档,终于找到一个解决方案----重新格式化XML,这样就有机会对XML重新编码并获取到想要String。
从此也想为什么不提供一个Document.asXML(String charset)的方法呢?看来还是Dom4j把中国人忽略了。
下面看看解决方案:
首先读入文件为String:
InputStream in = IssuePlan.
class.getClassLoader().getResourceAsStream(
"temp/test.xml");
if (in == null) {
log.info( "没有找到temp/test.xml");
}
String xml = StringFileToolkit.stream2String(in, charset);
Document doc = null;
try {
doc = DocumentHelper.parseText(xml);
doc.setXMLEncoding(charset);
} catch (DocumentException e) {
e.printStackTrace();
log.error( "XML格式错误,请检查temp/test.xml是否存在于Classpath下以及合理性!");
throw new Exception(e);
}
if (in == null) {
log.info( "没有找到temp/test.xml");
}
String xml = StringFileToolkit.stream2String(in, charset);
Document doc = null;
try {
doc = DocumentHelper.parseText(xml);
doc.setXMLEncoding(charset);
} catch (DocumentException e) {
e.printStackTrace();
log.error( "XML格式错误,请检查temp/test.xml是否存在于Classpath下以及合理性!");
throw new Exception(e);
}
这里将XML忠实的按照原有的编码读取出来了,注意,读取出来后,立即对doc对象指定编码,否则会按照操作系统默认的编码处理。
如果你在此处调用doc.asXML(),那么,就得到了这个XML文件UTF-8的编码,如果之间不是UTF-8,那么这样编码是错误的。
因此,要导出合理编码的字符串,还要调用格式方法,这个方法是我自己写的:
/**
* 格式化XML文档
*
* @param document xml文档
* @param charset 字符串的编码
* @return 格式化后XML字符串
*/
public static String formatXML(Document document, String charset) {
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding(charset);
StringWriter sw = new StringWriter();
XMLWriter xw = new XMLWriter(sw, format);
try {
xw.write(document);
xw.flush();
xw.close();
} catch (IOException e) {
log.error( "格式化XML文档发生异常,请检查!", e);
}
return sw.toString();
}
* 格式化XML文档
*
* @param document xml文档
* @param charset 字符串的编码
* @return 格式化后XML字符串
*/
public static String formatXML(Document document, String charset) {
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding(charset);
StringWriter sw = new StringWriter();
XMLWriter xw = new XMLWriter(sw, format);
try {
xw.write(document);
xw.flush();
xw.close();
} catch (IOException e) {
log.error( "格式化XML文档发生异常,请检查!", e);
}
return sw.toString();
}
你可以随意指定编码,但是你调用之前必须保证你的字符串编码和这里参数的编码一致,这样才是正确的调用。
-----------------------------------
这里还有一篇文章,但是忽略了或者是回避了Dom4j的转码问题: