XML解析中Bom导致错误的问题分析与解决

错误信息:org.dom4j.DocumentException:Error on line 1of document:Content is not allowed in prolog.

nested exception: Content is not allowed in prolog.

XML编码错误
左边报错的XML,右边正常的xml文件,比较工具Beyond Compare 4

解决办法:
1、使用Notepad++编辑器,将以UTF-8格式编码的文件转换为以UTF-8无Bom格式编码的文件,另存为即可。

2、对于webService接收来的xmlString的处理,使用如下方法修改xml字符串

/** * 检查xml字符串是否有非法前缀 * @param xmlStr * @return */
    public String checkXMLStr(String xmlStr){

        StringBuilder sb= new StringBuilder(xmlStr);
        int index = sb.indexOf("<?xml");
        if(index > 0){
            sb.delete(0,index);
            xmlStr = sb.toString();
        }else if(index == -1){
            xmlStr = "";
        }
        return xmlStr;

    }

3、为了程序的健壮性,可以在读文件的时候,加入判断,判断是否有Bom,有的话,在生成字符串的时候,将其删除方法如下:

/** * 检查byte数组 是否有BOM头 * UTF8文件都有一个3字节的头,为“EF BB BF”(称为BOM--Byte Order Mark) * @param bytes * @return */
    private static boolean CheckBOM( byte[] bytes )
    {
        boolean isBOM = false;
        {
            if(bytes.length >3){
                 if( 0xef == (bytes[0] & 0xff) 
                     && 0xbb == (bytes[1] & 0xff) 
                     && 0xbf == (bytes[2] & 0xff) ){
                     isBOM = true;
                 }
            }
        }
        //System.out.println("是否有BOM:"+isBOM);
        return isBOM;
    }
/** * 将文件读取为UTF-8编码字符串 * @param filePath * @return */
    public String getXMLFileText(String filePath) {
        String retXMLStr = "";

        byte[] bt = filetoByteArray(filePath);
        //加入一个判断,文件流是否含有Bom,有就删除
        if( CheckBOM(bt) ){
            try {
                retXMLStr = new String(bt,3,bt.length -3,"utf-8");
            } catch (UnsupportedEncodingException e) {
                // Todo Auto-generated catch block
                e.printstacktrace();
            }
        }else{
            try {
                retXMLStr = new String(bt,0,bt.length,"utf-8");
            } catch (UnsupportedEncodingException e) {
                // Todo Auto-generated catch block
                e.printstacktrace();
            }
        }
        //return checkXMLStr(retXMLStr);
        return retXMLStr;
    }
    // 将文件读成byte[]数组
    public byte[] filetoByteArray(String filePath) {

        filePath = filePath.replaceAll("\\\\","/");
        File file = null;
        FileInputStream fileInputStream = null;
        BufferedInputStream in = null;
        ByteArrayOutputStream out = null;
        byte[] bt = null;
        try {
            file = new File(filePath);

            if (!file.exists() || file.isDirectory()) {
                return null;
            }
            fileInputStream = new FileInputStream(file);

            in = new BufferedInputStream(fileInputStream);
            out = new ByteArrayOutputStream();
            byte[] temp = new byte[1024 * 1024];  //每次读取 1M
            int size = 0;
            while ((size = in.read(temp)) != -1) {
                out.write(temp,size);
            }

            bt = out.toByteArray();
            // for(int i = 0; i < bt.length; i++)

        } catch (Exception e) {
            e.printstacktrace();
        } finally {
            try {
                fileInputStream.close();
                in.close();
            } catch (IOException e) {
                // Todo Auto-generated catch block
                e.printstacktrace();
            }
        }

        return bt;
    }

问题分析:
某些文本编辑器或者Window系统,在保存XML时,会在文件开头自动加上Bom,dom4j会无法识别这个文件流。有人说1.3不能识别、1.6可以正常识别带Bom的UTF-8文件,但是我用的就是dom4j1.6,也会报这个错误

参考链接http://blog.sina.com.cn/s/blog_6d5d8b580100txon.html

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念