Intruder
IntruderҚаз. 4, 2019, 7:36 Т.Ж.

XML парсинг сложного тега <tag1> text part 1 <tag2> text </tag2> text part 2 </tag1>

Всем доброго времени суток.
Например есть вот такой тег:

<tag1> any text part 1 <tag2> text </tag2> any text part 2 </tag1>

Как реализовать корректное чтение и запись такой конструкции в объектную модель и модель QDom? С таким тегом сталкиваюсь впервые, поэтому не совсем понятно как действовать в такой ситуации.

Всем спасибо за помощь в решении даннго о вопроса.

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

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

7
Intruder
  • Қаз. 4, 2019, 7:52 Т.Ж.
  • (өңделген)

Я там описался, закрывающий последний тег - это

</tag1>
    Evgenii Legotckoi
    • Қаз. 4, 2019, 8:47 Т.Ж.

    Добрый день.
    А какой хотите получить итоговый результат? В том же QDomNode есть метод QDomNode::childNodes(), который возвратит список все вложенных тегов.

    То есть как раз для подобных случаев

    <body>
    <h1>Heading</h1>
    <p>Hello <b>you</b></p>
    </body>
    
      Intruder
      • Қаз. 4, 2019, 10:18 Т.Ж.

      Евгений, задача у меня следующая:
      1. Есть файл XML.
      2. Есть объектная модель, которая соответствует файлу XML.
      Мне нужно прорпарсить xml файл и записать значения в объектную модель.
      Я написал следующий код, примерный:

      #include <iostream>
      #include <QtXml/QDomDocument>
      #include <QFile>
      #include <QTextStream>
      
      int main()
      {
          QDomDocument doc;
          doc.appendChild(doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""));
          QDomElement element = doc.createElement("element");
          element.appendChild(doc.createTextNode("TEXT 1"));
          QDomElement element1 = doc.createElement("element1");
          element1.appendChild(doc.createTextNode("text1"));
          element.appendChild(element1);
          element.appendChild(doc.createTextNode("TEXT 2"));
          doc.appendChild(element);
          QFile file("C:/TEMP/test.xml");
          if(file.open(QIODevice::WriteOnly)){
              QTextStream out(&file);
              out.setCodec("UTF-8");
              out << doc.toString();
              file.close();
          }
          std::cout << "start import" << std::endl;
      
          QDomDocument doc1;
      
          if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
          {
              std::cout << "File not exist";
              return -1;
          }
          if(!doc1.setContent(&file)){
              file.close();
              return -1;
          }
          file.close();
              QDomNode node = doc1.firstChild();
                  while (!node.isNull()) {
                      QDomElement el1 = node.toElement();
                      std::cout << el1.tagName().toStdString() + el1.text().toStdString();
                      if(el1.hasChildNodes()){
                          QDomNode node1 = el1.firstChild();
                          while (!node1.isNull()) {
                              QDomElement el2 = node1.toElement();
                              std::cout << el2.tagName().toStdString() + " " + el2.text().toStdString() << std::endl;
                              node1 = node1.nextSibling();
                          }
                      }
                      node = node.nextSibling();
                  }
          return 0;
      }
      

      Так вот после создания файла XML получаю вот такое содержимое файла:

      <?xml version="1.0" encoding="UTF-8"?>
      <element>TEXT 1<element1>text1</element1>TEXT 2</element>
      


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

        Evgenii Legotckoi
        • Қаз. 6, 2019, 1:41 Т.Қ.

        Думаю, что вам также нужно какое-то дерево. Например, какой-нибудь TreeItem, который будет отражать одну ноду, и все child TreeItem будут сохраняться в в вектор, чтобы сохранять порядок элементов в теге.

        Что-нибудь вроде такого

        class TreeItem
        {
        public:
            TreeItem(TreeItem* parent = nullptr)
            {
                if (parent)
                {
                    parent->addChild(this);
                }
            }
        
            void addChild(TreeItem* child)
            {
                m_children.push_back(child);
            }
        
        private:
            TreeItem* m_parent;
            std::vector<TreeItem*> m_children;
        }
        

        QDomDocument - это тоже дерево. Поэтому при прохождении тегов можно составить своё собственное дерево. Но нужно понимать конечную цель.

          Intruder
          • Қаз. 6, 2019, 3:18 Т.Қ.

          Евгений, я думаю, что тут нужно будет разбирать строку. Дерево из QDomElement я построить могу - это не является какой-то сложной задачей. Задача не тривиальная потому, что если текст разбит на части внутри одного тега и эти части могут быть обернуты в дргуие теги, то, если взять значение головного тега, то он вернет строку целиком, т.е. захватит и текст других тегов. Вот в чем задача. Как разобрать строку и вернуть ее обратно именно в той последовательности, которая присутвует в файле. Есть наметки, но нужно проверить.

            Intruder
            • Қаз. 9, 2019, 6:52 Т.Ж.

            Евгений, а можно тогда уточнить вот такой момент. Были ли у вас случаи плана Мама мыла раму ? У меня собственно вопрос именно в этом, как взять и положить текст так в объект класса, чтобы потом модно было посторить обратно вышеописанную последовательность тегов?

              Evgenii Legotckoi
              • Қаз. 9, 2019, 3:45 Т.Қ.

              Добрый день.

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

              #include <iostream>
              #include <QtXml/QDomDocument>
              #include <QFile>
              #include <QTextStream>
              #include <QDebug>
              
              int main()
              {
                  QDomDocument doc;
                  doc.appendChild(doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""));
                  QDomElement element = doc.createElement("element");
                  element.appendChild(doc.createTextNode("TEXT 1"));
                  QDomElement element1 = doc.createElement("element1");
                  element1.appendChild(doc.createTextNode("text1"));
                  element.appendChild(element1);
                  element.appendChild(doc.createTextNode("TEXT 2"));
                  doc.appendChild(element);
                  QFile file("/home/dekadent/test.xml");
                  if(file.open(QIODevice::WriteOnly)){
                      QTextStream out(&file);
                      out.setCodec("UTF-8");
                      out << doc.toString();
                      file.close();
                  }
                  std::cout << "start import" << std::endl;
              
                  QDomDocument doc1;
              
                  if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
                  {
                      std::cout << "File not exist";
                      return -1;
                  }
                  if(!doc1.setContent(&file)){
                      file.close();
                      return -1;
                  }
              
                  file.close();
                  QDomNode node = doc1.firstChild();
              
                  while (!node.isNull()) {
                      QDomElement el1 = node.toElement();
                      std::cout << el1.tagName().toStdString() << " " << el1.text().toStdString() << std::endl;
                      if(el1.hasChildNodes()){
                          std::cout << "size of child nodes " << el1.childNodes().size() << std::endl;
                          for (int i = 0; i < el1.childNodes().size(); ++i)
                          {
                              std::cout << i << std::endl;
                              QDomNode node2 = el1.childNodes().item(i);
                              if (node2.isText())
                              {
                                  // Это текстовая нода, нужна иная обработка.
                                  std::cout << node2.toText().data().toStdString();
                              }
                              QDomElement el2 =  node2.toElement();
                              std::cout << el2.tagName().toStdString() << " " << el2.text().toStdString() << std::endl;
                          }
                      }
                      node = node.nextSibling();
                  }
                  return 0;
              }
              
              

              Весь прикол в том, что метод nextSibling() , который вы использовали, не работает на текстовые ноды, то есть на QDomText. Я сам об этом не знал. Сейчас только попробовал, поэкспериментировал и догадался, как это дело работает.

                Пікірлер

                Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
                Кіріңіз немесе Тіркеліңіз
                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…

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