2

今天我遇到了一个非常有趣的问题。当我尝试重写 xml 文件时。

我有 3 种方法可以做到这一点。我想知道问题的最佳方法和原因。

我。

File file = new File(REAL_XML_PATH);
         try {
         FileWriter fileWriter = new FileWriter(file);
         XMLOutputter xmlOutput = new XMLOutputter();

     xmlOutput.output(document, System.out);
     xmlOutput.output(document, fileWriter);

     fileWriter.close();
     } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
     }

在这种情况下,我的应用程序存在很大问题。用我自己的语言写文件后,我什么也看不懂。ANSI 上的编码文件已更改javax.servlet.ServletException: javax.servlet.jsp.JspException: Invalid argument looking up property: "document.rootElement.children[0].children"

二、

File file = new File(REAL_XML_PATH);
         XMLOutputter output=new XMLOutputter();
         try {
            output.output(document, new FileOutputStream(file));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

在这种情况下,我没有问题。编码没有改变。阅读和写作都没有问题。

而这篇文章http://tripoverit.blogspot.com/2007/04/javas-utf-8-and-unicode-writing-is.html

我想知道问题的最佳方法和原因。

4

2 回答 2

4

好吧,这看起来像问题:

FileWriter fileWriter = new FileWriter(file); 

那将始终使用平台默认编码,这很少是您想要的。假设您的默认编码是 ISO-8859-1。如果您的文档声明自己以 UTF-8 编码,但您实际上用 ISO-8859-1 编写所有内容,那么如果您有任何非 ASCII 字符,那么您的文件将无效 - 您最终会用ISO-8859-1 单字节表示,它不是有效的 UTF-8。

我实际上会提供一个流XMLOutputter而不是一个Writer. 这样,文件声明的编码和编写器使用的编码之间就没有冲突的余地。所以只需将您的代码更改为:

FileOutputStream fileOutput = new FileOutputStream(file);
...
xmlOutput.output(document, fileOutput);

...正如我现在看到的,您已经在第二段代码中完成了。所以是的,这是首选方法。在这里,流不对要使用的编码做任何假设,因为它只是要处理二进制数据。XML 编写代码决定二进制数据是什么,它可以确保它真正使用的字符编码与文件开头的声明相匹配。

应该清理您的异常处理 - 不要只打印堆栈跟踪并在失败时继续,并closefinally块中而不是在块的末尾调用try。如果您不能真正处理异常,请让它直接在堆栈中传播(可能throws会在您的方法中添加子句)或捕获它,记录它,然后重新抛出异常或更合适的异常来包装原因。

于 2012-08-31T06:12:52.900 回答
0

如果我没记错的话,您可以强制您的 xmlOutputter 使用“漂亮”格式: new XMLOutputter(Format.getPrettyFormat()) 所以它也应该适用于我

漂亮的是:

返回一个新的 Format 对象,该对象使用 2 空格缩进执行空白美化,使用 UTF-8 编码,不扩展空元素,包括声明和编码,并使用默认实体转义策略。可以对返回的 Format 实例进行调整,而不会影响其他实例。

于 2012-08-31T06:16:52.107 回答