最近做一个XML的生成与导入功能,生成的XML经过语法验证和Schema验证,均无错误,编码方式也是所要求UTF-8,可是导入时却一直提示:
Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prolog.
由于导入的系统时税务部门的网站,无从查看代码,跟踪异常,所有的信息只这一句莫名其妙的错误提示。
搜索后得知,可能是因为BOM引起的。
什么是BOM呢?
BOM:Byte Order Mark,中文名字节顺序标记。UCS规范建议在传输字节流前,先传输BOM来判断字节顺序。其实UTF-8是不需要用BOM来表明字节顺序的,但是可以用BOM来表明编码方式。BOM的UTF-8编码是EF BB BF,所以呢,如果接受者收到EF BB BF开头的字节流,就说明它是UTF-8编码了。
由此可见,对于UTF-8来说,BOM是可有可无的,可是,有的XML解析方式不认这个BOM,所以就报错了。
怎么判断XML是否含有BOM呢?
用UltraEdit或者其他可以带有十六进制编辑功能的软件打开XML,如果开头有EF BB BF就说明含有BOM了。
怎样去掉BOM呢?
可以用UltraEdit或者EmEditor打开XML,然后另存为,保存的时候有选项是以无BOM的UTF-8保存还是以有BOM的UTF-8保存。
怎样生成无BOM的XML呢?
要去掉生成的XML的BOM,要从源头上解决,不可能让用户每次生成XML后,手动编辑去掉BOM后再导入。
之前生成XML的代码是:
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = System.Text.Encoding.GetEncoding("utf-8");
XmlWriter writer = XmlWriter.Create(pathName, settings);
settings.Encoding = System.Text.Encoding.GetEncoding("utf-8");
XmlWriter writer = XmlWriter.Create(pathName, settings);
修改之后:
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = new UTF8Encoding(false);
XmlWriter writer = XmlWriter.Create(pathName, settings);
settings.Encoding = new UTF8Encoding(false);
XmlWriter writer = XmlWriter.Create(pathName, settings);
这样用XmlWriter生成的XML就是不带BOM的了,导入成功,不再报错。