zoukankan      html  css  js  c++  java
  • xmlWriter 以UTF-8格式写xml问题

    dom4j中的XMLWriter提供以下几种构造方法:

    XMLWriter() 
    XMLWriter(OutputFormat format) 
    XMLWriter(OutputStream out) 
    XMLWriter(OutputStream out, OutputFormat format) 
    XMLWriter(Writer writer) 
    XMLWriter(Writer writer, OutputFormat format) 

    最简单常用的可能是new XMLWriter(new FileWriter(...))这样的形式。可如果你一旦这么用,就会造成编码问题。由于dom4j对于文件编码的选择是用java本身类的处理方式(可以从源码看到),这么写就是采用FileWriter的处理方式,而FileWriter是不提供对编码的处理的。于是会调用系统自身的编码,比如用中文操作系统,编码方式就是gbk,但是它默认的在文件头写上<?xml version="1.0" encoding="UTF-8"?>。
    也就是说,他以当前操作系统的编码保存文件,并且竟然自动添加文件头为"utf-8"格式,这会导致很多程序无法读取正确编码,而且具有很差的移植性(比如在windows下开发,放到linux服务器下跑,毕竟一般linux服务器默认local都是utf-8)。

    解决途径一:

    使用new XMLWriter(new FileOutputStream(...))方法

    这样做,因为dom4j默认使用utf-8编码,即xml文件头默认编码方式,并且内容也会使用utf-8保存,这样可以做到一致的编码,不会出问题

    解决途径二:

    使用new XMLWriter(new FileOutputStream(...), outputFormat)的构造方法

    OutputFormat xmlFormat = OutputFormat.createPrettyPrint();
    xmlFormat.setEncoding("utf-8");
    XmLWriter writer = new XMLWriter(new FileOutputStream(...), xmlFormat);
    writer.write(document);
    writer.close();

    如上,setEncoding可以设置存储的文件编码格式,createPrettyPrint是得到美化xml格式输出。这样的话,在不同的环境下可以获得同样的编码读写,并且真正保证了文件标称与实际编码的一致性。

    注意如果使用OutputFormat是为了设置文件编码,那千万别用 XMLWriter(new FileWriter(...), outputFormat)构造方法,因为如前面所说,FileWriter不会处理编码,
    所以即使你使用format.setEncoding("utf-8");他仍然不会使用utf-8编码,而只是把文件头指定为utf-8,这类似不使用outputFormat的情况。

    以下为个人实践代码:

        /**
         * 输出xml文件
         * 
         * @param document
         * @param filePath
         * @throws IOException
         */
        public static void writeXml(Document document, String filePath) throws IOException {
            File xmlFile = new File(filePath);
            XMLWriter writer = null;
            try {
                if (xmlFile.exists())
                    xmlFile.delete();
                writer = new XMLWriter(new FileOutputStream(xmlFile), OutputFormat.createPrettyPrint());
                writer.write(document);
                writer.close();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (writer != null)
                    writer.close();
            }
        }
        @Test
        public void testXMLDoc() {
            try {
                String filePath = "E:/eXML.xml";
                Document document = XMLUtil.getDocument(filePath);
                Element root = null;
                document = XMLUtil.createDocument("vrvscript", "Class", "POLICY_BASE_LINE");
                root = document.getRootElement();
                root.addAttribute("P_ID", "12");
                root.addAttribute("StartPolicy", "1中文");
                root.addAttribute("PolicyVersion", "1.0");
                root.addAttribute("ScheduleMode", "6");
                root.addAttribute("ScheduleTime", "1:1:1");
                root.addAttribute("RuleHandle", "2");
                XMLUtil.writeXml(document, filePath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    测试结果发现:当写入的内容包含中文时产生的xml文件是UTF-8;但如果写入的内容中不包含中文,仅包含ANSI字符,那么产生的xml文件就是ANSI

    @Test
        public void testXMLDoc() {
            try {
                String filePath = "E:/eXML.xml";
                Document document = XMLUtil.getDocument(filePath);
                Element root = null;
                document = XMLUtil.createDocument("vrvscript", "Class", "POLICY_BASE_LINE");
                root = document.getRootElement();
                root.addAttribute("P_ID", "12");
                root.addAttribute("StartPolicy", "1");
                root.addAttribute("PolicyVersion", "1.0");
                root.addAttribute("ScheduleMode", "6");
                root.addAttribute("ScheduleTime", "1:1:1");
                root.addAttribute("RuleHandle", "2");
                XMLUtil.writeXml(document, filePath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

  • 相关阅读:
    python中的itertools模块简单使用
    SQLServer链接服务器
    @Valid和@Validated的区分总结
    禅道完成高成资本独家领投的数千万元融资
    青岛敏捷之旅,来了!
    linux主机互信操作
    小白学标准库之 mux
    小白学标准库之 flag
    音频截取分割打点标注工具
    大数据可能面试题
  • 原文地址:https://www.cnblogs.com/liaojie970/p/5280074.html
Copyright © 2011-2022 走看看