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

问题描述 投票:25回答:2

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

艾琳,提前谢谢

java xml encoding sax xml-parsing
2个回答
14
投票

当您希望Sax自动检测编码时,使用InputStream作为InputSource的参数。

如果要设置特定编码,请使用具有指定编码或setEncoding方法的Reader。

为什么?因为autodetection encoding algorithms需要原始数据,而不是转换为字符。

主题中的问题是:如何让SAX解析器从xml声明中确定编码?我发现Allan对这个问题的回答是误导性的,我根据JörnHorstmann的评论和我后来的经验提供了另一种选择。


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);
© www.soinside.com 2019 - 2024. All rights reserved.