crossplatform.ru

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


  Ответ в Пройтись по всем нодам QDomDocument без рекурсивных функций
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
Теги
Выровнять по центру
Ссылка на тему
Ссылка на сообщение
Скрытый текст
Сокращение
Код с подсветкой
Offtopic
 
Удалить форматирование
Спец. элементы
Шрифт
Размер
 
Цвет шрифта
 
Отменить ввод
Вернуть ввод
Полужирный
Курсив
Подчеркнутый
 
 
Смайлики
Вставить изображение
Вставить адрес электронной почты
Цитата
Код
Раскрывающийся текст
 
Увеличить отступ
По левому краю
По центру
По правому краю
Вставить список
Вставить список

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
lanz Дата 22.4.2013, 10:01
  Это я конечно маху дал, думал что QDomNodeList это typedef вроде QObjectList.
RazrFalcon Дата 20.4.2013, 20:23
  Немного переделал вариант от lanz, так как его не работал.
+ без доп функции пока никак...

QList<QDomNode> MyClass::childNodeList(QDomNode parent)
{
    QList<QDomNode> outList;
    QDomNodeList tmpList = parent.childNodes();
    for (int i = 0; i < tmpList.count(); ++i)
        outList << tmpList.at(i);
    return outList;
}

void MyClass::someClass()
{
    QList<QDomNode> list = childNodeList(m_svgNode);
    while (!list.empty()) {
        QDomElement currElem = list.takeAt(0).toElement();

        // stuff

        list << childNodeList(currElem);
    }
}


Вроде бы работает верно, и довольно короткая запись.
Алексей1153 Дата 15.4.2013, 18:57
  RazrFalcon, node.nextSibling(); находит соседний тег , таким образом ты перебираешь теги одного уровня в текущей "области видимости". Каждый тег помещаешь в стек. Новая итерация извлекает элемент и идёт уже по его чайлдам. Понимаешь фишку ? Поэтому в начале работы алгоритма важно инициализировать стек элементами первого уровня - ещё перед заходом в основной цикл перебора стека

кстати, nextSibling() без указания имени ищет любой следующий тег этого же уровня (скорее всего тег будет тот, что идёт в реальном тексте XML , но на это не стоит полагаться, мне кажется - не знаю, что на этот счёт говорит стандарт. Я всегда предполагаю, что порядок выбора может быть случайным)

если указать имя предыдущего элемента, найдётся элемент с таким же именем:

node.nextSibling(node.nodeName());


хотя, в твоём случае, с неизвестным контентом, это, наверное, не особо пригодится
lanz Дата 15.4.2013, 16:57
 
QDomNodeList list;

list.append (root_node);
while (!list.empty ()) {
    QDomElement el = list.takeAt (0).toElement ();
    do_stuff (el);
    list.append (el.childNodes ());
};

?
RazrFalcon Дата 15.4.2013, 13:58
  Да, такой способ я видел, но увы QDomDocument не умеет переходить на следующий элемент.
По этому такой вариант не работает:
    QDomNode node = m_doc.firstChild();
    while (!node.isNull()) {
        // some stuff
        node = node.nextSibling();
    }
Так как node.nextSibling не умеет проверять дочерние элементы. А так как структура xml мне заранее не известна, то не ясно как пройтись по дереву таким способом.
Алексей1153 Дата 14.4.2013, 15:25
  переход от рекурсии к итерации производится через создание собственного стека FILO (при рекурсии используется стек вызовов)

инициализация стека: кладём в стек первый (первые) элемент;

while(стек не пуст)
{
     извлечь текущий элемент из стека -> curr;

     исследование и обработка curr , в процессе обработки в стек заносятся ещё элементы;
}



Цитата
что бы можно было внутри какой-либо функции пройтись по всем элементам.

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

как вариант - работа с предикатом, шаблонная процедура
RazrFalcon Дата 13.4.2013, 23:34
  Обычный вариант с рекурсией:
void MyClass::process(QDomNode node)
{
    QDomNodeList nodeList = node.childNodes();
    for (int i = 0; i < nodeList.count(); ++i) {
        // some stuff
        if (node.childNodes().at(i).hasChildNodes())
            process(nodeList.at(i));
    }
}

Можно ли, как-то, это обернуть в while, что бы можно было внутри какой-либо функции пройтись по всем элементам. А то сейчас приходиться отдельную функцию заводить...
Просмотр темы полностью (откроется в новом окне)
RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 10.7.2025, 23:53