crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> QXmlStreamReader и большое количество уровней
SABROG
  опции профиля:
сообщение 13.7.2009, 14:50
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Решил попробовать класс QXmlStreamReader. Изучив пример streambookmarks я реализовал свой парсер. И вот что мне не понравилось. Можно написать простенький код, который будет сравнивать каждое название ключа на токен isStartElement с нужным нам. Недостаток такого метода - большое количество операций сравнений и падение скорости. Зато очень просто, когда ключи имеют уникальные имена, не нужно контролировать вложенность, родительские отношения. Второй вариант (правильный). На каждый уровень дерева выделяется отдельный метод с while(!atEnd()). Подобное выделение требует создание нового метода для каждого такого уровня. Если глубина дерева в xml'e большая, то можно себе представить какое огромное количество методов получится! Например у меня глубина дерева такая:

tourml/sources/source/packets/packet/packetheader/spo/dates/date


Т.е. 9 методов (на каждый уровень) и в каждом по циклу while(). При этом меня совершенно не интересуют промежуточные уровни, только последние.

Теперь сижу и думаю может сделать какие-нибудь указатели на методы, которые будут вызываться по очереди на одном while. Скажем QQueue/QHash с указателем на метод и строкой сравнения.
---
Только вот на самом деле там даже больше 9и методов получится, т.к. в xml'е еще другие блоки есть, такой например:

tourml/references/tourtypes/tourtype


Сообщение отредактировал SABROG - 13.7.2009, 14:59
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
ViGOur
  опции профиля:
сообщение 13.7.2009, 15:56
Сообщение #2


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Код в студию, можно занятся оптимизаторством и универсальностью кода. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 13.7.2009, 17:45
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(ViGOur @ 13.7.2009, 16:56) *
Код в студию, можно занятся оптимизаторством и универсальностью кода. :)

Давайте попробуем, коль не боитесь :)

Вот простой вариант:

    Q_ASSERT(isStartElement() && name() == "TourML");

    while (!atEnd()) {
        readNext();
        if (isStartElement()) {
            if (name() == "country") {
                qDebug() << attributes().value("nameLat");
            } else if (name() == "tour") {
                qDebug() << attributes().value("name");
            } else if (name() == "spo") {
                qDebug() << attributes().value("issue");
            } else if (name() == "priceQuantity") {
                qDebug() << readElementText();
            }
        }
}


Недостаток в том, что нет разбора кому какой ключ принадлежит. Т.е. если в xml'e будет 3 ветки и в каждой подветке будут ключи с одинаковыми именами, то я не смогу разобрать ключи "по кучкам".

А есть такая махина:

    Q_ASSERT(isStartElement() && name() == QLatin1String("TourML"));

    while (!atEnd()) {
        readNext();
        if (isStartElement()) {
            if (name() == QLatin1String("references")) {
                while (!(isEndElement() && name() == QLatin1String("references"))) {
                    readNext();
                    if (isStartElement() && name() == QLatin1String("countries")) {
                        while (!(isEndElement() && name() == QLatin1String("countries"))) {
                            readNext();
                            if (isStartElement() && name() == QLatin1String("country"))
                                qDebug() << attributes().value(QLatin1String("nameLat"));
                        }
                    }
                }
            } else if (name() == QLatin1String("sources")) {
                while (!(isEndElement() && name() == QLatin1String("sources"))) {
                    readNext();

                    if (isStartElement() && name() == QLatin1String("source")) {
                        while (!(isEndElement() && name() == QLatin1String("source"))) {
                            readNext();
                            if (isStartElement() && name() == QLatin1String("packets")) {
                                while (!(isEndElement() && name() == QLatin1String("packets"))) {
                                    readNext();
                                    if (isStartElement() && name() == QLatin1String("packet")) {
                                        while (!(isEndElement() && name() == QLatin1String("packet"))) {
                                            readNext();
                                            if (isStartElement() && name() == QLatin1String("packetHeader")) {
                                                while (!(isEndElement() && name() == QLatin1String("packetHeader"))) {
                                                    readNext();
                                                    if (isStartElement()) {
                                                        if (name() == QLatin1String("tour")) {
                                                            qDebug() << attributes().value(QLatin1String("name"));
                                                        } else if (name() == QLatin1String("spo")) {
                                                            qDebug() << attributes().value(QLatin1String("issue"));
                                                        } else if (name() == QLatin1String("spoInfo")) {
                                                            while (!(isEndElement() && name() == QLatin1String("spoInfo"))) {
                                                                readNext();
                                                                if (isStartElement() && name() == QLatin1String("priceQuantity"))
                                                                    qDebug() << readElementText();
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }


Соответственно тут и так всё понятно. Плюс в том, что тут я точно знаю какой ветке что принадлежит.

По скорости и первый и второй варианты почти одинаковы. XML файл на 5,5Мб парсится ~297ms.

Сообщение отредактировал SABROG - 13.7.2009, 18:21
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме
- SABROG   QXmlStreamReader и большое количество уровней   13.7.2009, 14:50
- - ViGOur   Код в студию, можно занятся оптимизаторством и уни...   13.7.2009, 15:56
|- - SABROG   Цитата(ViGOur @ 13.7.2009, 16:56) Код в с...   13.7.2009, 17:45
- - ViGOur   Жесть! А почему нельзя сделать рекурсию с соз...   13.7.2009, 19:29
- - SABROG   Цитата(ViGOur @ 13.7.2009, 20:29) А почем...   13.7.2009, 20:28
- - SABROG   Да уж, что-то не очень получается. Если делать рек...   14.7.2009, 14:25
- - SABROG   В общем посмотрел я десяток примеров использования...   14.7.2009, 22:40
- - ViGOur   Ты немного не понял, рекурсия c примерно таким усл...   15.7.2009, 10:32
- - SABROG   Да оно всё это понятно, я тоже об этом говорю. Сам...   15.7.2009, 11:14
- - ViGOur   Так в том то и дело, что в твоем случае как я поня...   15.7.2009, 12:24
- - Tonal   То, что тут пытаетесь изобразить, называется конеч...   15.7.2009, 12:38
- - SABROG   Как я и писал выше затык будет в заполнении таблиц...   15.7.2009, 13:16
- - SABROG   Такой вопрос насчет QXmlStreamReader::PrematureEnd...   15.7.2009, 21:35
- - SABROG   Нашел забавную статью про StAX, пример рассматрива...   22.7.2009, 15:33
- - SABROG   Сегодня заметил статью в блоге на QtSoftware и о т...   24.7.2009, 13:27
- - Litkevich Yuriy   Цитата(SABROG @ 24.7.2009, 17:27) я немно...   24.7.2009, 13:39
- - SABROG   В общем я немного заморочился на эту тему и напи...   29.8.2009, 14:40


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 1.12.2022, 17:21