Как позволить парсеру SAX определить кодировку из объявления xml? - PullRequest
25 голосов
/ 14 августа 2010

Я пытаюсь проанализировать 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 без какой-либо конкретной настройки? Мне это нужно, потому что я не знаю заранее, какой будет кодировка файла.

Спасибо заранее, Allan

Ответы [ 2 ]

14 голосов
/ 04 сентября 2012

Используйте InputStream в качестве аргумента для InputSource , когда вы хотите, чтобы Sax автоматически определил кодировку.

Если вы хотите установить определенную кодировку, используйте Reader с указанной кодировкой или setEncoding метод.

Почему?Поскольку алгоритмы кодирования автоопределения требуют необработанных данных, не преобразуемых в символы.

Вопрос в теме: Как разрешить анализатору SAX определять кодировку из объявления xml? Я нашел ответ Аллана на вопрос вводящим в заблуждение и предоставил альтернативный ответ, основанный на комментарии Йорна Хорстманна и моем последующем опыте.

9 голосов
/ 14 августа 2010

Я нашел ответ сам.

Анализатор 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);
...