2013-05-09 2 views
0

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

Это приложение анализирует файлы xml, которые закодированы в ISO-8859-15 (aka 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 [email protected]:1 in [email protected]) 

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

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

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

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


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

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

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

ответ

0

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

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

org.xmlpull.v1.XmlPullParserException: unexpected type (position:END_DOCUMENT [email protected]:1 in [email protected]) 

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

вызова следующего() и возвращает событие, если оно START_TAG или END_TAG иначе сгенерирует исключение.