Подтвердить что ты не робот

Как разрешить парсер SAX определять кодировку из объявления xml?

Я пытаюсь разобрать 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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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