Intruder
IntruderҚыр. 3, 2019, 4:52 Т.Қ.

Как оптимизировать код и вызывать рекурсивно?

Всем доброго времени суток.
У меня есть задача просмотреть все теги в xml-файле и остановиться на нужном, как только он будет найден, т.е. вернуть объект QDomElement, чтобы дальше с ним работать. Я данную задачу решаю в лоб (тут пока простой вывод названия тегов). Т.е., так как я знаю какова вложенность тегов, то я просто выполняю следующий код:

    QDomElement docElem = doc.documentElement();
    QDomNode n1 = docElem.firstChild();
    while(!n1.isNull()){
        QDomElement e1 = n1.toElement(); // try to convert the node to an element.
        if(!e1.isNull()){
            qDebug() << qPrintable(e1.tagName()); // the node really is an element.
            if(e1.hasChildNodes())
            {
                QDomNode n2 = e1.firstChild();
                while(!n2.isNull()){
                    QDomElement e2 = n2.toElement();
                    if(!e2.isNull()){
                        qDebug() << qPrintable("    " + e2.tagName());
                        if(e2.hasChildNodes()){
                            QDomNode n3 = e2.firstChild();
                            while (!n3.isNull()) {
                                QDomElement e3 = n3.toElement();
                                qDebug() << qPrintable("        " + e3.tagName());
                                if(e3.hasChildNodes()){
                                    QDomNode n4 = e3.firstChild();
                                    while (!n4.isNull()){
                                        QDomElement e4 = n4.toElement();
                                        qDebug() << qPrintable("            " + e4.tagName());
                                        if(e4.hasChildNodes()){
                                            QDomNode n5 = e4.firstChild();
                                            while (!n5.isNull()) {
                                                QDomElement e5 = n5.toElement();
                                                qDebug() << qPrintable("                " + e5.tagName());
                                                if(e5.hasChildNodes()){
                                                    QDomNode n6 = e5.firstChild();
                                                    while (!n6.isNull()) {
                                                        QDomElement e6 = n6.toElement();
                                                        qDebug() << qPrintable("                    " + e6.tagName());
                                                        n6 = n6.nextSibling();
                                                    }
                                                }
                                                n5 = n5.nextSibling();
                                            }
                                        }
                                        n4 = n4.nextSibling();
                                    }
                                }
                                n3 = n3.nextSibling();
                            }
                        }
                    }
                    n2 = n2.nextSibling();
                }
            }
        }
        n1 = n1.nextSibling();
    }

Вроде бы ничего сложного нет, но это уж слишком грамоздко. Хотелось бы использовать рекурсию. Но логически я понимаю что нужно делать, но как это реализуется на практике для меня темный лес. Перечитал много примеров и с числами Фибоначи, и с решением факториала. Но переложить на свой пример что-то не получается. Нужно ли вводить глобальные переменные, необходимые для посчета итераций? И тому подобное?

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

3
IscanderChe
  • Қыр. 4, 2019, 2:17 Т.Ж.

Вот пример, как это сделано у меня.

В основном теле делается вызов функции readReport , а потом он же делается внутри функции рекурсивно, до конца дерева документа. Безо всяких глобальных переменных.

Основное тело

QDomDocument domDoc;
QFile file(pathToFile);

if(file.open(QIODevice::ReadOnly))
{
  if(domDoc.setContent(&file))
  {
    QDomElement domElement = domDoc.documentElement();
    readReport(domElement);
  }
  file.close();
}
else
{
  qDebug() << "Error reading file!";
  exit (1);
}

readReport

readReport(const QDomNode& node)
{
    QDomNode domNode = node.firstChild();
    while(!domNode.isNull())
    {
        if(domNode.isElement())
        {
            QDomElement domElement = domNode.toElement();
            if(!domElement.isNull())
            {
                if(domElement.tagName() == "TestFunction")
                {
                    functionItem = new QTreeWidgetItem(caseItem);
                    functionItem->setText(0, domElement.attribute("name", "") + "()");
                    if(domElement.attribute("name", "") == "initTestCase"
                            || domElement.attribute("name", "") == "cleanupTestCase")
                    {
                        QPalette pal;
                        functionItem->setTextColor(0, QColor(Qt::darkGray));
                    }
                }
                else if(domElement.tagName() == "Incident")
                {
                    if(domElement.attribute("type", "") == "pass")
                    {
                        functionItem->setText(1, "Passed!");
                        QFont font;
                        font.setBold(true);
                        functionItem->setFont(1, font);
                        QPalette pal;
                        functionItem->setTextColor(1, QColor(Qt::darkGreen));
                    }
                    else
                    {
                        functionItem->setText(1, "Failed!");
                        QFont font;
                        font.setBold(true);
                        functionItem->setFont(1, font);
                        functionItem->setTextColor(1, QColor(Qt::red));
                    }
                }
                else if(domElement.tagName() == "Description")
                    functionItem->setText(2, domElement.text());
            }
        }
        readReport(domNode);
        domNode = domNode.nextSibling();
    }
}
    Evgenii Legotckoi
    • Қыр. 4, 2019, 2:36 Т.Ж.
    • (өңделген)
    • Жауап шешім ретінде белгіленді.

    Добрый день.

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

    #include <QDomDocument>
    
    void readElements(const QDomElement& element)
    {
        QDomNode childNode = element.firstChild();
        while (!childNode.isNull()) 
        {
            QDomElement childElement = childNode.toElement();
            qDebug() << qPrintable("                " + childElement.tagName());
            if (childElement.hasChildNodes())
            {
                readElements(childElement);
            }
            childNode = childNode.nextSibling();
        }
    }
    
    
    void readDoc(const QDomDocument& doc)
    {
        QDomElement docElem = doc.documentElement();
        readElements(docElem);
    }
    
      Intruder
      • Қыр. 5, 2019, 3 Т.Қ.

      В общем я написал вот такую функцию, которая возвращает список искомых элементов QDomElement

      void Descriptionlib::searchXmlElementsList(QVector<QDomElement> *domelementlist, QDomElement &domelement, const QString &searchtag)
      {
      
          QDomNode domNode = domelement.firstChild();
          while (!domNode.isNull()) {
              QDomElement element = domNode.toElement();
              //qDebug() << qPrintable(element.tagName());
              if(element.tagName() == searchtag)
              {
                  QDomElement resultElement = element;
                  domelementlist->append(element);
              } else if(element.hasChildNodes()){
                  searchXmlElementsList(domelementlist, element, searchtag);
              }
              domNode = domNode.nextSibling();
          }
      }
      

      Спасибо всем, кто откликнулся.

        Пікірлер

        Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
        Кіріңіз немесе Тіркеліңіз
        OI
        • Ora Iro
        • Жел. 24, 2024, 6:38 Т.Ж.

        C++ - Тест 001. Первая программа и типы данных

        • Нәтиже:40ұпай,
        • Бағалау ұпайлары-8
        AD

        C++ - Тест 004. Указатели, Массивы и Циклы

        • Нәтиже:50ұпай,
        • Бағалау ұпайлары-4
        m
        • molni99
        • Қаз. 26, 2024, 1:37 Т.Ж.

        C++ - Тест 004. Указатели, Массивы и Циклы

        • Нәтиже:80ұпай,
        • Бағалау ұпайлары4
        Соңғы пікірлер
        ИМ
        Игорь МаксимовҚар. 22, 2024, 11:51 Т.Ж.
        Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
        Evgenii Legotckoi
        Evgenii LegotckoiҚаз. 31, 2024, 2:37 Т.Қ.
        Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
        A
        ALO1ZEҚаз. 19, 2024, 8:19 Т.Ж.
        Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
        ИМ
        Игорь МаксимовҚаз. 5, 2024, 7:51 Т.Ж.
        Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
        d
        dblas5Шілде 5, 2024, 11:02 Т.Ж.
        QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
        Енді форумда талқылаңыз
        p
        pimacontrols85Жел. 31, 2024, 9:39 Т.Ж.
        Finding the Right Rittal Small Enclosure for Your Needs Rittal is a leading manufacturer of enclosures for industrial and IT applications. Their small enclosures offer a compact and reliable solution for a wide range of needs, from housing electronic…
        Donald Randolph
        Donald RandolphЖел. 30, 2024, 2:59 Т.Ж.
        Personal Injury lawyer Santa Monica As an experienced Santa Monica personal injury lawyer, Donald C. Randolph has recovered over $100 Million in verdicts and settlements for our clients. In severe injury cases, this compensation i…
        Nirvana Yoga School
        Nirvana Yoga SchoolЖел. 30, 2024, 5:13 Т.Ж.
        OAuth2.0 через VK, получение email Nirvana Yoga School is one of the most trusted and reputed traditional Rishikesh yoga courses , India certified by Yoga Alliance, USA. We aim to spread traditional yoga teachings so t…
        s
        sriparkЖел. 30, 2024, 4:47 Т.Ж.
        Mobile app development company in Chennai A Mobile app development company in Chennai focuses on creating personalized mobile applications to meet various business requirements. These companies offer a full range of services,…
        a
        amit88Жел. 30, 2024, 4:45 Т.Ж.
        Excel in Exams with PSLE Maths Tuition Singapore Preparing for the PSLE can be challenging, but the right guidance makes all the difference. PSLE Maths tuition Singapore offers personalized coaching to help students master key concepts, improv…

        Бізді әлеуметтік желілерде бақылаңыз