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

Есть ли более простой способ анализа XML в Java?

Я пытаюсь понять, как разбирать некоторые XML (для Android-приложения), и кажется довольно смешным, как трудно это сделать на Java. Похоже, для этого требуется создание обработчика XML, который имеет различные обратные вызовы (startElement, endElement и т.д.), И вы должны затем позаботиться об изменении всех этих данных на объекты. Что-то вроде этот учебник.

Все, что мне действительно нужно, - это изменить XML-документ в многомерный массив, и даже лучше будет иметь какой-то Hpricot процессор. Есть ли способ сделать это, или мне действительно нужно написать весь дополнительный код в приведенном выше примере?

4b9b3361

Ответ 1

Существует два разных типа процессоров для XML в Java (фактически, но один из них странный). У вас есть парсер SAX и то, что вы хотите, это парсер DOM. Посмотрите http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/на использование парсера DOM. DOM создаст дерево, которое можно легко перемещаться. SAX лучше всего подходит для больших документов, но DOM намного проще, если медленнее и интенсивнее.

Ответ 2

Попробуйте http://simple.sourceforge.net, его XML-сериализацию и привязку к Java, полностью совместимую с Android и очень легкую, 270K и без зависимостей.

Ответ 3

Ознакомьтесь с этой статьей для способов обработки XML на Android. Возможно, стиль DOM или XML Pull подходит вашему стилю лучше

Работа с XML на Android

Ответ 4

Кайл

(Прошу извинить природу самопомощи этого поста... Я работаю над этой библиотекой в ​​течение нескольких месяцев, и все это с открытым исходным кодом /Apache 2, так что это не самообслуживание, а просто пытается помочь).

Я только что выпустил библиотеку, которую я вызываю SJXP или "Простой Java XML Parser", http://www.thebuzzmedia.com/software/simple-java-xml-parser-sjxp/

Это очень маленький/плотный (4 класса) слой абстракции, который находится поверх любого совместимого с производительностью XML Pull Parser.

На платформах Android и не-Android Java вытягивание разбора, вероятно, является одним из самых эффективных (как в скорости, так и при низкой памяти) методах разбора. К сожалению, кодирование непосредственно против синтаксического анализатора выглядит так же, как любой другой XML-синтаксический код (например, SAX) - у вас есть обработчики исключений, поддерживающие состояние анализатора, проверка ошибок, обработка событий, разбор значений и т.д.

Что делает SJXP, это позволяет вам определять "пути" в стиле XPath в документе элементов или атрибутов, из которых вы хотите получить значения, например:

/RSS/канал/название

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

Код для стандартного анализатора будет выглядеть примерно так (пример, который анализирует заголовок RSS2):

IRule titleRule = new DefaultRule(Type.CHARACTER, "/rss/channel/title") {
@Override
public void handleParsedCharacters(XMLParser parser, String text) {
    // Store the title in a DB or something fancy
}}

то вы просто создаете экземпляр XMLParser и даете ему все правила, о которых вы хотите его заботиться:

XMLParser parser = new XMLParser(titleRule);
parser.parse(xmlStream);

И что он, парсер будет вызывать метод обработчика каждый раз, когда правило будет соответствовать. Вы можете прекратить разбор в любое время, вызвав parser.stop(), если хотите.

Кроме того (и это реальный выигрыш в этой библиотеке) сопоставление элементов и атрибутов пространства имен невозможен, вы просто добавляете свой URI пространства имен внутри скобок, префиксного имени элемента на вашем пути.

В качестве примера скажем, что вы хотите получить элемент для RSS-канала, чтобы вы могли указать, на каком языке он находится (ссылка: http://web.resource.org/rss/1.0/modules/dc/). Вы просто используете уникальный URI пространства имен для этого элемента "language" с префиксом "dc", а путь к правилам выглядит следующим образом:

/Новости/канал/[http://purl.org/dc/elements/1.1/] язык

То же самое относится и к атрибутам с атрибутом имен.

При всей этой простоте единственные накладные расходы, которые вы добавляете к процессу синтаксического анализа, - это поиск хэша O (1) в каждом месте документа XML и несколько сотен байтов, возможно, 1k для внутреннего местоположения анализатора.

Библиотека работает на Android без каких-либо дополнительных зависимостей (поскольку платформа уже предоставляет org.xmlpull impl) и в любой другой среде выполнения Java, добавляя зависимость XPP3.

Эта библиотека является результатом многомесячного написания пользовательских синтаксических парсеров для каждого вида XML-фида на каждом языке и реализации (с течением времени) того, что около 90% парсинга можно отделить от этой действительно базовой парадигмы.

Надеюсь, вам будет удобно.

Ответ 5

Начиная с Java 5, в SDK есть библиотека XPath. См. этот учебник для ознакомления с ним.

Ответ 6

По мне, вы должны использовать SAX-парсер, потому что: - Быстро - вы можете управлять всем в документе XML

Вы будете платить больше времени на кодирование, но это один раз, потому что вы создадите шаблон кода для анализа XML

Во втором случае вы редактируете только содержание изменений.

Удачи!

Ответ 7

Я создал действительно простой API для решения именно этой проблемы. Это всего лишь один класс, который вы можете включить в свою базу кода, и он действительно чист и легко разбирает любой XML. Вы можете найти его здесь:

http://argonrain.wordpress.com/2009/10/27/000/

Ответ 8

Вы можете попробовать это http://xml.jcabi.com/
Это дополнительный слой поверх DOM, который позволяет простой синтаксический анализ, печать и преобразование документов и узлов XML.

Ответ 9

Вы также можете использовать Castor для сопоставления XML с Java beans. Я использовал его раньше, и он работает как шарм.

Ответ 10

Написание SAX handler - лучший способ. И как только вы это сделаете, вы никогда не вернетесь ни к чему другому. Он быстрый, простой и он хрустит, когда он идет, не сосать большие части или бог запретить целое DOM в память.

Ответ 11

Несколько недель назад я избил небольшую библиотеку (обертка вокруг javax.xml.stream.XMLEventReader), позволяющую анализировать XML аналогично ручному рекурсивному парсеру спуска. Источник доступен для github, а пример простого использования ниже. К сожалению, Android не поддерживает этот API, но он очень похож на API XmlPullParser, который поддерживается, а перенос не будет слишком трудоемким.

accept("tilesets");
    while (atTag("tileset")) {
        String filename = attrib("file");
        File tilesetFile = new File(filename);
        if (!tilesetFile.isAbsolute()) {
            tilesetFile = new File(FilenameUtils.concat(file.getParent(), filename));
        }
        int tilesize = Integer.valueOf(attrib("tilesize"));
        Tileset t = new Tileset(tilesetFile, tilesize);
        t.setID(attrib("id"));
        tilesets.add(t);

        accept();
        close();
    }
close();

expect("map");

int width       = Integer.valueOf(attrib("width"));
int height      = Integer.valueOf(attrib("height"));
int tilesize    = Integer.valueOf(attrib("tilesize"));

Ответ 12

На мой взгляд, использование XPath для анализа XML может быть вашим самым простым подходом к кодированию. Вы можете воплотить логику вытягивания узлов из XML-документа в одном выражении, вместо того, чтобы писать код для перемещения графа объекта документа.

Я отмечаю, что другой ответ на этот вопрос уже предложил использовать XPath. Но еще не для вашего Android-проекта. На данный момент класс разбора XPath еще не поддерживается ни в одной версии Android (хотя пространство имен javax.xml определено в JVM Davlik, которое может вас обмануть, так как оно меня сначала).

Включение класса XPath в Android - это текущий рабочий элемент на поздней стадии. (Он проверяется и отлаживается Google, когда я пишу это). Вы можете отслеживать статус добавления XPath в Davlik здесь: http://code.google.com/p/android/issues/detail?id=515

(Это раздражение, которое вы не можете считать вещами, поддерживаемыми на большинстве виртуальных машин Java, еще включено в Android Davlik VM.)

Другим вариантом при ожидании официальной поддержки Google является JDOM, который в настоящее время утверждает совместимость с Dalvik VM, а также поддержку XPath (в бета). (Я не проверял это, я просто повторяю текущие заявления со своего веб-сайта.)

Ответ 13

Существует очень хороший пример для XmlPullParser для любого типа xml. Он также может анализировать как общий способ, вам не нужно ничего менять, чтобы просто получить этот класс и поместить в свой проект Android.

Общий XmlPullParser

Ответ 14

Хорошо разбирать XML - непростая задача.

Его основная структура - это дерево с любым node в дереве, которое может содержать контейнер, состоящий из массива большего количества деревьев.

Каждый node в дереве содержит тег, а значение, но в дополнении может содержать произвольное количество именованных атрибутов и суровое число дочерних элементов или контейнеров.

Задачи синтаксического анализа XML, как правило, попадают в три категории.

Вещи, которые можно сделать с помощью "регулярного выражения". Например. вы хотите найти значение первого тега "MailTo" и не интересуетесь содержимым любых других тегов.

Вещи, которые вы можете проанализировать самостоятельно. Структура xml всегда очень проста, например, root node и десять хорошо известных тегов с простыми значениями.

Все остальное! Несмотря на то, что формат XML-сообщений может выглядеть обманчиво, простые домашние парсеры легко путаются дополнительными атрибутами, CDATA и неожиданными детьми. Полноразмерные анализаторы XML могут обрабатывать все эти ситуации. Здесь основной выбор между потоком или парсером DOM. Если вы намерены использовать большинство сущностей/атрибутов, заданных в том порядке, в котором вы хотите их использовать, тогда парсер DOM идеален. Если вас интересуют только несколько атрибутов и намереваются использовать их в том порядке, в котором они представлены, если у вас есть ограничения производительности, или, если файлы xml большие ( > 500 МБ), чем способ анализа потока; механизм обратного вызова принимает немного "groking", но его на самом деле довольно просто программировать, как только вы его повесите.