在最近的一个项目,经常需要读取XML进行预处理,将处理后内容写入中间文件(xml),
现在出现的一个问题是,某些中间文件,在JDOM载入进行build时,报出如下错误:
Error: Error on line 1 of document file:/C:/eclipse/workspace/Cmd/deleteme1.xml: Content is not
allowed in prolog.
打开此文件,发现其第一行内容为:
<?xml version="1.0" encoding="UTF-8"?>
通过UltraEdit查看其16进制,发现前面3个字符(6个字节)为:
C3 AF C2 BB C2 BF;
查看原文件,开头含有两字节FF FE;对比其他文件并不含。
此处需要插入BOM头的内容:
引用
UTF的字节序和BOM
UTF -8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如 “
奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是 “乙”?
Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想
法:
在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传
输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。
这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH
NO-BREAK SPACE"又被称作BOM。
UTF -8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是 EF BB BF(读者可以
用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
Windows就是使用BOM来标记文本文件的编码方式的。
请参考:
谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
现在发现就是出错文件含有BOM头,而在读取时并没有使用相应encoding,
BufferedReader br = new BufferedReader(new FileReader(oldFile));
这样读取使用的话,应该是使用的eclipse默认编码(与当前Java文件编码相同?),还没想明白。
解决办法如下:
BufferedReader br = new BufferedReader(new FileReader(oldFile));
br.mark(10);
int b1,b2,b3;
String readEncoding = defaultReadEncoding;
b1 = br.read();
b2 = br.read();
b3 = br.read();
if(b1==0xef && b2==0xbb && b3==0xbf){
readEncoding = "UTF8";
}else if(b1== 0xfe && b2==0xff){
readEncoding = "UnicodeBig";
}else if(b1== 0xff && b2==0xfe){
readEncoding = "UnicodeLittle";
}
if(readEncoding==null){
br.reset();
}else{
br.close();
FileInputStream fis = new FileInputStream(oldFile);
InputStreamReader isr = new InputStreamReader(fis, readEncoding);
br = new BufferedReader(isr);
}
而在写入时,使用代码
FileOutputStream fos = new FileOutputStream(newFile);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos, "UTF8"));
这是没有问题的,前面出现问题是因为使用了错误的编码读取了6个错误字节而在写入前已经出现错误。
还有些东西、点没想通,再补充。
分享到:
相关推荐
使用Xstream解析复杂xml文件,并读入MySql数据库中
DOM解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过遍历树结构可以检索任意XML节点,读取它的属性和值。而且通常情况下,可以借助XPath,直接查询XML节点。 SAX解析XML,是基于事件通知的...
易语言源码易语言读入xml到高级表格源码.rar 易语言源码易语言读入xml到高级表格源码.rar 易语言源码易语言读入xml到高级表格源码.rar 易语言源码易语言读入xml到高级表格源码.rar 易语言源码易语言读入xml到...
功能:创建XML文件的根节点 参数:[in] sName 根节点的节点名 返回:true创建成功 false创建失败 **************************************/ bool CreateRootNode(CString sName); /************************...
DOM解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过遍历树结构可以检索任意XML节点,读取它的属性和值。而且通常情况下,可以借助XPath,直接查询XML节点。 SAX解析XML,是基于事件通知的...
XML解析器,支持XML读入解析和写XML. 需要使用XML的朋友可以看一下
l xmlread(), 用于读取XML文件内容,读入后的变量是一个Java XML object。 l xmlwrite(), 用于写入XML文件内容,同样输出变量也要是一个Java XML Object。 l xslt(),用于stylesheet转换的问题,所以就没有关系。 ...
解析XML的方式有很多种,大家比较熟悉的可能就是DOM解析。 DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了。 优点:整个文档读入内存,...
2 读入XML文件bookA.xml,加入一条处理指令,修改第一本书的价格和作者,并添加一条属性,然后写入文件bookB.xml 3 解析abc.xml文档,读取所有属性和子节点并输出 4 解析parse.xml文档,创建方法新增节点、根据ID...
xml文件被Sax解析器载入,由于Sax解析是按照xml文件的顺序来解析,当读入<?xml.....>时,会调用startDocument()方法,当读入的时候,由于它是个ElementNode,所以会调用startElement(String uri, String local...
要求:定义一个XML文件,保存本班学生的学号,姓名,性别,出生日期等,如上次实验所示。使用C#编写WINFORM程序,实现对学生信息在XML中信息的存取。
本篇文章主要介绍了C++读入XML文件,读取和设置xml配置文件是最常用的操作,TinyXML是一个开源的解析XML的C++解析库,感兴趣的小伙伴们可以参考一下。
python xml解析 first.xml <id>1 <name>fsy <age>24 <id>2 <name>jianjian <age>24 <count id ='1'>1000 from xml.etree import ElementTree as etree 读入 def read_xml(file): # parse()函数会返回...
&1.XML简介 XML的背景 1) XML代表可扩展的标记语言(eXtensible Markup Language); 2) XML由W3C联盟发展维护; 3) XML是一种元语言,可以用来定义其它标签语言; 4) XML没有定义任何标记,它提供了一种工具定义...
标准的IEEE14节点数据是标准的XML格式文件存储,通过Java程序解析XML文件,读入潮流计算所需要的数据,最后进行PQ潮流计算
读取XML格式,并且解析代码,以供大家遇到这类问题,能带来一点帮助
SAX(simple API for XML),是基于事件处理的,当XML文档顺序地读入时,每次遇到一个元素会触发相应的事件处理函数来处理。DOM(Document Object Model),通过构建一个树结构来表现整个xml文档,一旦树被构建,...
不同浏览器都有自己的解析器,把XML读入内存,并把它转换为可被 JavaScript 访问的 XML DOM 对象。 微软的 XML 解析器与其他浏览器中的解析器是有差异的。微软的解析器支持对 XML 文件和 XML 字符串(文本)的加载,...
本文主要介绍在Android中怎样来解析XML文件。主要采用的是SAX机制,SAX全称为Simple API for XML,它既是一种接口,也是一个软件包。作为接口,SAX是事件驱动型XML解析的一个标准接口。XML文件解析一般有2种方法,...