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. Я сам об этом не знал. Сейчас только попробовал, поэкспериментировал и догадался, как это дело работает.

                Пікірлер

                Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
                Кіріңіз немесе Тіркеліңіз
                AD

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

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

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

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

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

                • Нәтиже:20ұпай,
                • Бағалау ұпайлары-10
                Соңғы пікірлер
                ИМ
                Игорь МаксимовҚар. 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 аналогично. Могу предположить, что из-за более новой верси…
                Енді форумда талқылаңыз
                m
                moogoҚар. 22, 2024, 7:17 Т.Ж.
                Mosquito Spray System Effective Mosquito Systems for Backyard | Eco-Friendly Misting Control Device & Repellent Spray - Moogo ; Upgrade your backyard with our mosquito-repellent device! Our misters conce…
                Evgenii Legotckoi
                Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
                добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                t
                tonypeachey1Қар. 15, 2024, 6:04 Т.Ж.
                google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                NSProject
                NSProjectМаусым 4, 2022, 3:49 Т.Ж.
                Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…

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