Intruder
Intruder7. Juni 2019 15:46

XML парсинг! Подскажите правильно ли я делаю или есть способ легчее и проще?

Желаю всем здравствия и прошу совета и/или помощи в реализации XML парсинга.
У меня есть что-то типа вот такой стуктуры данных в XML:

<?xml version="1.0" encoding="UTF-8"?>
<Data>
    <Group>
        <Object>
            <ObjectIdent contextIdent="Context identificator" itemOriginator="orig02">Object identificator</ObjectIdent>
            <ObjectInfo>
                <ObjectName>Object name</ObjectName>
                <pNumber>PartNumber</pNumber>
                <ObjectVariantIdent>text 1</ObjectVariantIdent>
                <ObjectVariantIssue>text 2</ObjectVariantIssue>
                <temperature>
                    <minTemperature unitOfMeasure="C">10</minTemperature>
                    <maxTemperature unitOfMeasure="C">45</maxTemperature>
                </temperature>
            </ObjectInfo>
        </Object>
    </Group>
</Data>

И есть функция сбора XML-файла и соответсвенно разбора.
Вот они

    /* Объявление объекта file */
    QFile file(namefile);
    QDir currentDir;
    currentDir.setCurrent(pathfile);
    file.open(QFile::WriteOnly);
    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);  // Устанавливаем автоформатирование текста
    xmlWriter.writeStartDocument();     // Запускаем запись в документ
    xmlWriter.writeStartElement("Data"); 
    xmlWriter.writeStartElement("Group"); 
    xmlWriter.writeStartElement("Object");
    xmlWriter.writeStartElement("ObjectIdent");
    if(dataObj.Obj().IdentObj().contextIdentAttr() != "") {
        xmlWriter.writeAttribute("contextIdent", dataObj.Obj().IdentObj().contextIdentAttr());
    }
    if(dataObj.Obj().IdentObj().manufacturerCodeAttr() != ""){
        xmlWriter.writeAttribute("manufacturerCodeValue", dataObj.Obj().IdentObj().manufacturerCodeAttr());
    }
    QString itemOriginatorStr = dataObj.Obj().IdentObj().itemOriginatorAttr(dataObj.Obj().IdentObj());
    if(dataObj.Obj().IdentObj().itemOriginatorAttr(dataObj.Obj().IdentObj()) != "Null"){
        xmlWriter.writeAttribute("itemOriginator", itemOriginatorStr);
    }

    xmlWriter.writeCharacters(Obj().IdentObj().IdentItem().toUtf8());
    xmlWriter.writeEndElement(); 
    xmlWriter.writeStartElement("ObjectInfo");
    if(dataObj.Obj().InfoObj().getName() != ""){
        xmlWriter.writeStartElement("ObjectName");
        xmlWriter.writeCharacters(Obj().InfoObj().getName());
        xmlWriter.writeEndElement();
    }

    if(Obj().InfoObj().getpNumber().pnumber() != ""){
        xmlWriter.writeStartElement("pNumber"); 
        xmlWriter.writeCharacters(Obj().InfoObj().getpNumber().pnumber());
        xmlWriter.writeEndElement();
    }

    if(harnessObj().harnessInfoObj().getHarnessVariantIdent() != ""){
        xmlWriter.writeStartElement("ObjectVariantIdent"); 
        xmlWriter.writeCharacters(Obj().InfoObj().getVariantIdent());
        xmlWriter.writeEndElement(); 
    }
    if(Obj().InfoObj().getVariantIssue() != ""){
        xmlWriter.writeStartElement("ObjectVariantIssue"); 
        xmlWriter.writeCharacters(Obj().InfoObj().getVariantIssue());
        xmlWriter.writeEndElement(); 
    }
    if(Obj().InfoObj().getTemperature().minTemperature() != NULL || Obj().InfoObj().getTemperature().maxTemperature() != NULL){
        xmlWriter.writeStartElement("temperature");
        if(Obj().InfoObj().getTemperature().minTemperature() != NULL){
            xmlWriter.writeStartElement("minTemperature");
            QString unitOfmeasureStr = Obj().InfoObj().getUnitOfMeasure(Obj().InfoObj());
            xmlWriter.writeAttribute("unitOfMeasure", unitOfmeasureStr);
            xmlWriter.writeCharacters(QString::number(Obj().InfoObj().getTemperature().minTemperature()));
            xmlWriter.writeEndElement();
        }
        if(Obj().InfoObj().getTemperature().maxTemperature() != NULL){
            xmlWriter.writeStartElement("maxTemperature");
            QString unitOfmeasureStr = Obj().harnessInfoObj().getUnitOfMeasure(harnessObj().harnessInfoObj());
            xmlWriter.writeAttribute("unitOfMeasure", unitOfmeasureStr);
            xmlWriter.writeCharacters(QString::number(Obj().InfoObj().getTemperature().maxTemperature()));
            xmlWriter.writeEndElement();
        }
        xmlWriter.writeEndElement();
    }
    xmlWriter.writeEndElement(); 

    xmlWriter.writeEndElement(); 
    xmlWriter.writeEndElement(); 
    xmlWriter.writeEndElement(); 
    xmlWriter.writeEndDocument();
    file.close();

Функция разбора:

    /* Объявление объекта file */
    QFile file(namefile);
    QDir currentDir;
    currentDir.setCurrent(pathfile);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "File not exist";
        return nullptr;
    }
    Obj *newObj = new Obj();
    Ident *newIdent = new Ident();
    Info *newInfo = new Info();
    pNumber *newpNumber = new pNumber();
    TempElemType *newTempElemType = new TempElemType();

    QXmlStreamReader xmlReader(&file);
    xmlReader.readNext(); // Читаем следующий элемент

    while (!xmlReader.atEnd()) //Запускаем цикл чтения XML-файла, с условием пока не достигнем конца файла
    {
        if(xmlReader.isStartElement()) //Если это начало элемента, то проверяем...
        {
            if(xmlReader.name() == "ObjectIdent"){
                foreach (const QXmlStreamAttribute &attr, xmlReader.attributes()){
                    if(attr.name() == "contextIdent"){
                        newIdent->setContextIdentAttr(attr.value().toString());
                    }else if (attr.name() == "itemOriginator") {
                        newIdent->setItemOriginatorAttr(itemOriginatorAttr(attr.value().toString()));
                    }else if (attr.name() == "manufacturerCodeValue") {
                        newIdent->setManufacturerCodeAttr(attr.value().toString());
                    }
                }
                newIdent->setIdentItem(xmlReader.readElementText());
            }
            if(xmlReader.name() == "ObjectInfo"){
                while (!xmlReader.atEnd()) {
                    if(xmlReader.name() == "ObjectName"){
                        newInfo->setName(xmlReader.readElementText());
                    }
                    if (xmlReader.name() == "pNumber") {
                        newpNumber->setpnumber(xmlReader.readElementText());
                    }
                    if (xmlReader.name() == "ObjectVariantIdent") {
                        newInfo->setVariantIdent(xmlReader.readElementText());
                    }
                    if (xmlReader.name() == "ObjectVariantIssue") {
                        newInfo->setVariantIssue(xmlReader.readElementText());
                    }
                    if(xmlReader.name() == "temperature"){
                        while (!xmlReader.atEnd()) {
                            if(xmlReader.name() == "minTemperature"){
                                foreach (const QXmlStreamAttribute &attr, xmlReader.attributes()) {
                                    if(attr.name() == "unitOfMeasure" && attr.value() == "degC"){
                                        newTempElemType->setUnitOfmeasure(UnitOfMeasure::degC);
                                    }
                                    if (attr.name() == "unitOfMeasure" && attr.value() == "degF") {
                                        newTempElemType->setUnitOfmeasure(UnitOfMeasure::degF);
                                    }
                                }
                                int minTemp = xmlReader.readElementText().toInt();
                                newTempElemType->setMinTemperature(minTemp);
                            }
                            if(xmlReader.name() == "maxTemperature"){
                                foreach (const QXmlStreamAttribute &attr, xmlReader.attributes()) {
                                    if(attr.name() == "unitOfMeasure" && attr.value() == "degC"){
                                        newTempElemType->setUnitOfmeasure(UnitOfMeasure::degC);
                                    }else if (attr.name() == "unitOfMeasure" && attr.value() == "degF") {
                                        newTempElemType->setUnitOfmeasure(UnitOfMeasure::degF);
                                    }
                                }
                                int maxTemp = xmlReader.readElementText().toInt();
                                newTempElemType->setMaxTemperature(maxTemp);
                            }
                            xmlReader.readNextStartElement();
                        }
                    }
                    xmlReader.readNextStartElement();
                }
            }
        }
        xmlReader.readNext();
    }

В общем как-то так. Так как объект бужет очень большой, то функции сбора/разбора XML получаются очень длинными. В связи с этим у меня два вопроса:
1. Правильно ли я делаю сбор/разбор XML или что-то делаю неправильно/упускаю?
2. Нет ли инструментария обертывания в XML в Qt по типу как это сделаю в C#?

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

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

1
Evgenii Legotckoi
  • 10. Juni 2019 03:59

Добрый день!

Да разбор-то вы правильно делаете. Просто здесь нужно продумывать архитектуру самого XML, а также классов которые будут отвечать за парсинг.

В принципе всё можно разбить на классы Property, которые будут иметь аттрибуты ключа и значения. А также будут иметь вложенных детей, которые также будут иметь класс Property.

А что касается самого парсинга, то можно посмотреть в сторону QDomDocument . Он будет получше для подобных задач.

Собственного говоря смысл будет в том, чтобы каждая Property, могла записывать данные в QDomDocument и считывать их. У вас будет строиться дерево из объектов Property.

    Kommentare

    Nur autorisierte Benutzer können Kommentare posten.
    Bitte Anmelden oder Registrieren
    Letzte Kommentare
    A
    ALO1ZE19. Oktober 2024 08:19
    Fb3-Dateileser auf Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
    ИМ
    Игорь Максимов5. Oktober 2024 07:51
    Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
    d
    dblas55. Juli 2024 11:02
    QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
    k
    kmssr8. Februar 2024 18:43
    Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
    Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
    Jetzt im Forum diskutieren
    J
    JacobFib17. Oktober 2024 03:27
    добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
    JW
    Jhon Wick1. Oktober 2024 15:52
    Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
    КГ
    Кирилл Гусарев27. September 2024 09:09
    Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
    F
    Fynjy22. Juli 2024 04:15
    при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

    Folgen Sie uns in sozialen Netzwerken