Альтернатива встроенному XmlPullParser с хорошей поддержкой кодирования.

Я портирую проект, написанный для BlackBerry (Java), на Android. Проект содержит несколько классов синтаксического анализа xml, написанных для интерфейса org.xmlpull.v1.XmlPullParser. фактический экземпляр парсера внедряется в эти классы извне.

Это приложение анализирует XML-файлы, закодированные в ISO-8859-15 (или Latin 9). Я не могу использовать UTF-8, к сожалению, мне нужно придерживаться этой кодировки.

В старом проекте BlackBerry использовался анализатор запросов kxml2. Сейчас в андроиде пытался использовать встроенный парсер, который можно получить вот так:

XmlPullParser parser = Xml.newPullParser();

И затем я настраиваю кодировку символов:

parser.setInput(<input stream>, "ISO-8859-15");

Проблема в том, что этот парсер не поддерживает эту кодировку символов. Это исключение:

org.xmlpull.v1.XmlPullParserException: Error parsing document. (position:line -1, column -1) caused by: org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 0: unknown encoding.

И это действительно странно, потому что я знаю, что Android поддерживает эту кодировку. Доказательство в том, что эта строка работает без исключений:

String test  = new String("hi".getBytes(), "ISO-8859-15");

Однако, если я настрою синтаксический анализатор для другой кодировки, например UTF-8 или latin-1, он сработает.

Следующее, что я попробовал, это использовать парсер старого проекта (kxml2) в Android, но потом я получил новые ошибки:

org.xmlpull.v1.XmlPullParserException: unexpected type (position:END_DOCUMENT null@9:1 in java.io.InputStreamReader@43e97088)

Даже если бы я мог использовать его без проблем, kxml2 не получал поддержки в последние годы (последняя версия выпущена в 2006 году), поэтому я хотел бы использовать синтаксический анализатор Android, если это возможно, который более надежен и также имеет лучшую производительность. .

Я могу обмануть синтаксический анализатор по умолчанию, вызывающий parser.setInput(bais, "ISO-8859-1");, потому что таким образом он игнорирует кодировку в объявлении XML в файле, и это работает, потому что оба набора символов имеют одинаковое количество символов, и большинство из них одинаковы. Но таким образом кто-то, глядя на исходный код, может подумать, что он использует латиницу-1, когда на самом деле он получает ввод на латинице-9 и, следовательно, создает строки на латинице-9.

Есть ли какая-либо причина, по которой синтаксический анализатор извлечения XML по умолчанию не поддерживает ISO-8859-15? Есть ли альтернативная библиотека разбора PULL с хорошей поддержкой кодировки символов?

Заранее спасибо.


ОБНОВЛЕНИЕ: когда я писал вопрос, я тестировал парсер по умолчанию в ОС 2.2 и 2.3. Однако, прочитав javadoc для Xml.newPullParser, я нашел это:

Примечание. На самом деле он работает медленнее, чем анализатор SAX, и реализован не полностью. Если вам нужен быстрый, в основном реализованный синтаксический анализатор запросов, используйте это. Если вам нужна полная реализация, используйте KXML.

И действительно, при тестировании дефолтного парсера в OS 4.x я получил второе исключение. Похоже, для OS 4 встроенный парсер на самом деле kxml!!


person Mister Smith    schedule 09.05.2013    source источник


Ответы (1)


Что ж, похоже, трудно найти хорошую библиотеку XmlPullParser, поэтому я собираюсь использовать синтаксический анализатор kxml, следуя советам в javadocs для Xml.newPullParser фабричного метода. (Я не нашел эту заметку в онлайн-документах javadoc, только в окне javadoc eclipse. Возможно, я использую старые документы javadoc, и это примечание было позже удалено после того, как Android начал использовать kxml в качестве встроенного синтаксического анализатора).

Что касается исключения, возникающего при использовании синтаксического анализатора kxml, это было так:

org.xmlpull.v1.XmlPullParserException: unexpected type (position:END_DOCUMENT null@9:1 in java.io.InputStreamReader@43e97088)

Оказалось, что это было вызвано моим кодом. В начальном порте я понял, что встроенный анализатор Android, включенный в Froyo и Gingerbread, не переходит к следующему тегу после вызова parser.nextText. Поэтому я добавил несколько строк parser.nexTag здесь и там, чтобы заставить его работать. Затем я снова переключился на kXml, но сохранил эти лишние строки, из-за которых мой экземпляр KXmlParser запутался при обработке конца файла. Исключение возникает при вызове nextTag после достижения конца файла. Это также объясняется в документации для nextTag:

Вызовите next() и верните событие, если оно START_TAG или END_TAG, в противном случае создайте исключение.

person Mister Smith    schedule 10.05.2013