Подсчет элементов XML в файле на Android - PullRequest
2 голосов
/ 06 апреля 2010

Возьмите простой XML-файл, отформатированный так:

<Lists>
<List>
<Note/>
...
<Note/>
</List>
<List>
<Note/>
...
<Note/>
</List>
</Lists>

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

Я могу сделать это с помощью простого поиска строки или чего-то подобного, но мне нужно сделать это как можно быстрее.

Расчетные параметры:
Должно быть в Java (приложение для Android).
Необходимо ИЗБЕГАТЬ выделять как можно больше памяти.
Должно возвращать общее количество элементов Note и количество элементов List в файле независимо от их расположения в файле.

Количество списков, как правило, будет небольшим (1-4), а количество примечаний может быть очень большим (свыше 1000, обычно 100) на файл.

Я с нетерпением жду ваших предложений.

Ответы [ 4 ]

2 голосов
/ 06 апреля 2010

XmlPullParser - это анализатор потоковой передачи XML, который следует использовать, когда необходимо быстро и эффективно обработать все элементы ввода.

Вы можете попробовать что-то вроде этого:

private void pullParserSample(FileInputStream xml) {
    int lists = 0;
    int notes = 0;
    int eventType = -1;

    try {
        XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
        xpp.setInput(new InputStreamReader(xml));

        eventType = xpp.getEventType();

        do {
            switch ( eventType ) {

            case XmlPullParser.START_TAG:
                final String tag = xpp.getName();
                if ( "Note".equals(tag) ) {
                    notes++;
                }
                else if ( "List".equals(tag) ) {
                    lists++;
                }
                break;

            }

        } while ((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT) ;

    } catch (XmlPullParserException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Log.d(TAG, "lists=" + lists + " notes=" + notes);
}
1 голос
/ 06 апреля 2010

Если вы просто хотите считать элементы в тексте, а не анализировать документ, вы можете прочитать каждую строку из файла в последовательности и проверить с помощью класса Pattern / Matcher (я забыл, какой), соответствует ли строка "<Note> "или" <List> "и увеличиваем счетчики соответственно.

РЕДАКТИРОВАТЬ: Альтернативная идея

Прочитайте документ по одному символу за раз, когда вы встретите символ «<», начните добавлять все последующие символы, которые не являются символом «>», в StringBuilder. Затем, когда вы встретите символ «>», сравните строку StringBuilder с «Заметкой» или «Списком» или чем-то еще и, соответственно, увеличьте счетчики. Наконец, очистите StringBuilder и повторяйте до конца документа.

0 голосов
/ 06 апреля 2010

быстрое грязное непроверенное решение, используя сгенерированный конечный автомат Ragel . Передайте это ragel, который сгенерирует для вас код Java.

Полученный код будет использовать анализатор FSM на основе таблиц с постоянным требованием к памяти (таблицы и переменная состояния). Он также может принимать частичные данные, вы можете возобновить его в любой позиции.

Это, вероятно, будет быстрее, чем любой синтаксический анализатор общего назначения или регулярные выражения системы.

(Отказ от ответственности: я не программист на Java, и нижеприведенное ниже никоим образом не является полным, поскольку в нем отсутствует необходимый для запуска скелетный код. Однако, это вполне может быть неплохой основой для начала.)

%%{
    machine nodecounter;

    note = '<Note' @{notes++;};
    list = '<List' ^'s' @{lists++;};
    set = note | list;
    main := (set | ^set)*;
}%%

%% write data;

%% write init;

/* */
%% write exec;
0 голосов
/ 06 апреля 2010

Посмотрите на реализацию org.xml.sax.ContentHandler и отправьте его в org.xml.sax.XMLReader.

Эти классы связаны с Android SDK. Это подход «прямого синтаксического анализа», при котором вашему ContentHandler показывается каждый элемент XML (тег, атрибут, текст) при обработке документа от начала до конца. Подход прямого синтаксического анализа - это легкое использование памяти и намного быстрее, чем создание DOM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...