如何让SAX解析器从xml声明中确定编码?

时间:2010-08-14 07:51:12

标签: java xml encoding sax xml-parsing

我正在尝试解析来自不同来源的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声明中检测到正确的编码?我需要这个,因为我事先不知道文件的编码是什么。

提前致谢, 艾伦

2 个答案:

答案 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);