我正在尝试解析来自不同来源的xml文件(我无法控制)。其中大多数都是用UTF-8编码的,并且使用以下代码段不会导致任何问题:
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
FeedHandler handler = new FeedHandler();
InputSource is = new InputSource(getInputStream());
parser.parse(is, handler);
由于SAX默认为UTF-8,这很好。但是有些文件声明:
<?xml version="1.0" encoding="ISO-8859-1"?>
即使ISO-8859-1被声明为SAX,仍然默认为UTF-8。 只有我添加:
is.setEncoding("ISO-8859-1");
SAX会使用正确的编码。
如果我没有专门设置它,我如何让SAX自动从xml声明中检测到正确的编码?我需要这个,因为我事先不知道文件的编码是什么。
提前致谢, 艾伦
答案 0 :(得分:14)
当您希望Sax自动检测编码时,使用 InputStream 作为InputSource的参数。
如果要设置特定编码,请使用指定编码或setEncoding方法的 Reader 。
为什么呢?因为autodetection encoding algorithms需要原始数据,而不是转换为字符。
主题中的问题是:如何让SAX解析器从xml声明中确定编码?我发现Allan对这个问题的回答是错误的,我提供了另一个,基于JörnHorstmann的评论和我以后的经历。
答案 1 :(得分:9)
我自己找到了答案。
SAX解析器在内部使用InputSource,并使用InputSource文档:
SAX解析器将使用 InputSource对象确定如何 读取XML输入。如果有的话 字符流可用,解析器 将直接读取该流, 无视任何文本编码 在该流中发现的声明。如果 没有字符流,但是 有一个字节流,解析器 将使用该字节流,使用 InputSource中指定的编码 否则(如果没有指定编码) 自动检测字符编码 使用诸如之类的算法 XML规范。如果不是 字符流也不是字节流 可用,解析器将尝试 打开与资源的URI连接 由系统标识符标识。
所以基本上你需要将一个字符流传递给解析器,以便它获取正确的编码。请参阅以下解决方案:
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
FeedHandler handler = new FeedHandler();
Reader isr = new InputStreamReader(getInputStream());
InputSource is = new InputSource();
is.setCharacterStream(isr);
parser.parse(is, handler);