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);
        }
 
这里将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();
        }
 
你可以随意指定编码,但是你调用之前必须保证你的字符串编码和这里参数的编码一致,这样才是正确的调用。
 
-----------------------------------
这里还有一篇文章,但是忽略了或者是回避了Dom4j的转码问题: