demo,迅雷链接。或者我主页上传的资源
链接:https://pan.xunlei.com/s/VO8bIvYFfhmcrwF-7wmcPW1SA1?pwd=nrp4#
复制这段内容后打开手机迅雷App,查看更方便
qt_c++_xml存这种复杂类型-LMLPHP

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <QTextCodec>
#include <QFile>
#include <QDomDocument>
#include <QTextStream>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE


typedef struct
{
    QString num_name;
    QString subFcParaName;
    double workMin;
    double workMax;

}attachedCondition;

class ConditionClass
{
public:
    ConditionClass(){};
    ~ConditionClass(){};

    QString fcParaName;
    double earlyMin;
    double earlyMax;
    double alarmMin;
    double alarmMax;

    QList<attachedCondition>attached_contidition_;

};



class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();


    void removeNode(QString xml_path,QString node_name);
    void updateNode(QString xml_path,QList<ConditionClass>all_condition_);

    void loadXml(QString xml_path);

    void createXML(QString filePath);

   QDomElement createAttributrNode(QDomDocument &doc,QString attribute_value,QString node_name);
   QDomElement createNode(QDomDocument &doc,QString value,QString node_name);
   QDomElement createNode(QDomDocument &doc,double value,QString node_name);
   void appendXml(QDomDocument &doc,QDomElement &root,QList<ConditionClass>all_condition_);
    //这是要存进去的数据
     QList<ConditionClass>all_condition_;

     //这是要读取出来的数据
     QList<ConditionClass>read_all_data_;


private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ConditionClass it;
    it.fcParaName="油压";
    it.earlyMin=55;
    it.earlyMax=66;
    it.alarmMax=88;
    it.alarmMin=77;

    attachedCondition at;
    at.num_name="附属1";
    at.subFcParaName="高度表";
    at.workMin=5;
    at.workMax=6;
    it.attached_contidition_.append(at);

    attachedCondition at0;
    at0.num_name="附属2";
    at0.subFcParaName="液压油温度";
    at0.workMin=5;
    at0.workMax=6;
    it.attached_contidition_.append(at0);


    ConditionClass it0;
    it0.fcParaName="1发N1";
    it0.earlyMin=55;
    it0.earlyMax=66;
    it0.alarmMax=88;
    it0.alarmMin=77;

    attachedCondition at00;
    at00.num_name="附属1";
    at00.subFcParaName="机油温度";
    at00.workMin=5;
    at00.workMax=6;
    it0.attached_contidition_.append(at00);

    all_condition_.append(it);

    all_condition_.append(it0);


    QString path= "C:/Users/36075/Desktop/ycn_xml/xml_ycn/warnRuler.xml";

    createXML(path);
    removeNode(path,"1发N1");
    removeNode(path,"油压");
    updateNode( path,all_condition_);
    loadXml(path);




}

MainWindow::~MainWindow()
{
    delete ui;
}

/**
    * @brief 创建一个xml文档
    * @param 路径
    * @param 基本参数
    */
void MainWindow::createXML(QString filePath)
{

           QFile file(filePath);

               bool isOk = file.open(QIODevice::ReadWrite);
                if(file.size()!=0)
                {
                    return;
                }

                 QDomDocument doc;
                 QDomProcessingInstruction instruction;
                     instruction=doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
                     doc.appendChild(instruction);

                     QDomElement root = doc.createElement("root");
                       doc.appendChild(root);

                     appendXml(doc,root,this->all_condition_);
                  //   appendXml(doc,root,this->all_condition_);

                 QTextStream stream(&file);
                     stream.setCodec("UTF_8");
                     doc.save(stream,4,QDomNode::EncodingFromTextStream);
                     file.close();

}

 void MainWindow::loadXml(QString xml_path)
{
    QFile file(xml_path);
    if(!file.open(QFile::ReadOnly | QFile::Text))
    {
        return;
    }

    QString strError;
    int errorLine;
    int errorColumn;
    QDomDocument doc;
    if(!doc.setContent(&file, false, &strError, &errorLine, &errorColumn)){
        return;
    }
    QDomElement root = doc.documentElement();
    if(root.tagName() == "root")
    {
        QDomNode first = root.firstChild();
        while(!first.isNull())
        {

            ConditionClass cc;
            if(first.toElement().tagName() == "主参数")
            {
                QString str = first.toElement().attribute("主参数");
                qDebug()<<str;
                cc.fcParaName=str;
                QDomNode node = first.firstChild();
                while(!node.isNull())
                {
                    if(node.toElement().tagName() == "earlyMin")
                    {
                        QString earlyMin = node.toElement().text();
                        qDebug()<<earlyMin;
                        cc.earlyMin=earlyMin.toDouble();
                    }
                    if(node.toElement().tagName() == "earlyMax")
                    {
                        QString earlyMax = node.toElement().text();
                        qDebug()<<earlyMax;
                        cc.earlyMax=earlyMax.toDouble();
                    }
                    if(node.toElement().tagName() == "alarmMax")
                    {
                        QString alarmMax = node.toElement().text();
                        qDebug()<<alarmMax;
                        cc.alarmMax=alarmMax.toDouble();
                    }
                    if(node.toElement().tagName() == "alarmMin")
                    {
                        QString alarmMin = node.toElement().text();
                        qDebug()<<alarmMin;
                        cc.alarmMin=alarmMin.toDouble();
                    }
                    if(node.toElement().tagName() == "附属")
                    {

                        //访问附属下面的子节点
                        QString attri = node.toElement().attribute("附属");
                        qDebug()<<attri;

                         QDomNode attrinode = node.firstChild();
                            while(!attrinode.isNull())
                            {
                             attachedCondition atc;

                                //附属1里面的子节点内容访问一下
                               qDebug()<<attrinode.toElement().tagName();
                                 atc.num_name=attrinode.toElement().tagName();

                                QDomNode attrinode1 = attrinode.firstChild();
                                    while(!attrinode1.isNull())
                                    {
                                        if(attrinode1.toElement().tagName() == "参数名")
                                        {
                                            QString diany = attrinode1.toElement().text();
                                            qDebug()<<diany;
                                            atc.subFcParaName=diany;
                                        }
                                        if(attrinode1.toElement().tagName() == "workMin")
                                        {
                                            QString diany = attrinode1.toElement().text();
                                            qDebug()<<diany;
                                            atc.workMin=diany.toDouble();
                                        }
                                        if(attrinode1.toElement().tagName() == "workMax")
                                        {
                                            QString diany = attrinode1.toElement().text();
                                            qDebug()<<diany;
                                            atc.workMax=diany.toDouble();
                                        }
                                        attrinode1=attrinode1.nextSibling();
                                    }
                                cc.attached_contidition_.append(atc);
                                 attrinode = attrinode.nextSibling();
                            }


                    }


                    node = node.nextSibling();
                }
            }

            this->read_all_data_.append(cc);
            first = first.nextSibling();
        }
    }
    file.close();

}

/**
    * @brief 打开路径下的xml文档,删除指定名称的节点
    * @param 路径
    * @param 基本参数
    */
void MainWindow::removeNode(QString xml_path,QString node_name)
{
    QFile file(xml_path);
    if(!file.open(QFile::ReadOnly|QFile::WriteOnly | QFile::Text))
    {
        return;
    }


    QString strError;
    int errorLine;
    int errorColumn;
    QDomDocument doc;
    if(!doc.setContent(&file, false, &strError, &errorLine, &errorColumn)){
        return;
    }

    file.close();

    QDomElement root = doc.documentElement();
    if(root.tagName() == "root")
    {

        QDomNode first = root.firstChild();
        while(!first.isNull())
        {
            if(first.toElement().attribute("主参数") ==node_name)
            {

                   root.removeChild(first);
                 //  break;

            }
            first = first.nextSibling();
        }


    }

    if(!file.open(QFile::WriteOnly|QFile::Truncate))
           return;

       QTextStream out_stream(&file);
       doc.save(out_stream,4); //缩进4格
       file.close();


}

/**
    * @brief 打开xml文档,然后往里面写数据
    * @param
    * @param
    */
void MainWindow::updateNode(QString xml_path,QList<ConditionClass>all_condition_)
{

    QFile file(xml_path); //相对路径、绝对路径、资源路径都可以
       if(!file.open(QFile::ReadOnly))
           return;

       //增加一个一级子节点以及元素
       QDomDocument doc;
       if(!doc.setContent(&file))
       {
           file.close();
           return;
       }
       file.close();

       QDomElement root=doc.documentElement();


    if(all_condition_.isEmpty())
    {

        return;
    }


    for(auto it:all_condition_)
    {

        auto fcParaName=it.fcParaName;
        auto earlyMin= it.earlyMin;
        auto earlyMax=  it.earlyMax;
        auto alarmMax=  it.alarmMax;
        auto alarmMin=  it.alarmMin;


        auto main_para= createAttributrNode(doc,fcParaName,"主参数");
        root.appendChild(main_para);

        main_para.appendChild(createNode(doc,earlyMin,"earlyMin"));
        main_para.appendChild(createNode(doc,earlyMax,"earlyMax"));
        main_para.appendChild(createNode(doc,alarmMax,"alarmMax"));
        main_para.appendChild(createNode(doc,alarmMin,"alarmMin"));

        if(!it.attached_contidition_.isEmpty())
        {

            auto attribute_para=createAttributrNode(doc,"附属","附属");
            main_para.appendChild(attribute_para);

        for(auto item:it.attached_contidition_)
        {
            int i=0;
            //QString attribute_para=tr("附属")+QString::number(i);
            QString num_name=item.num_name;
            QString subFcParaName=item.subFcParaName;
            double workMin=item.workMin;
            double workMax=item.workMax;

            auto at= createAttributrNode(doc,num_name,num_name);
            at.appendChild(createNode(doc,subFcParaName,"参数名"));
            at.appendChild(createNode(doc,workMin,"workMin"));
            at.appendChild(createNode(doc,workMax,"workMax"));

           attribute_para.appendChild(at);
            i++;
        }

        }
    }

    if(!file.open(QFile::WriteOnly|QFile::Truncate))
           return;

       QTextStream out_stream(&file);
       doc.save(out_stream,4); //缩进4格
       file.close();

}

void MainWindow::appendXml(QDomDocument &doc,QDomElement &root,QList<ConditionClass>all_condition_)
{

    for(auto it:all_condition_)
    {

        auto fcParaName=it.fcParaName;
        auto earlyMin= it.earlyMin;
        auto earlyMax=  it.earlyMax;
        auto alarmMax=  it.alarmMax;
        auto alarmMin=  it.alarmMin;

        auto main_para= createAttributrNode(doc,fcParaName,"主参数");
        root.appendChild(main_para);

        main_para.appendChild(createNode(doc,earlyMin,"earlyMin"));
        main_para.appendChild(createNode(doc,earlyMax,"earlyMax"));
        main_para.appendChild(createNode(doc,alarmMax,"alarmMax"));
        main_para.appendChild(createNode(doc,alarmMin,"alarmMin"));

        if(!it.attached_contidition_.isEmpty())
        {

            auto attribute_para=createAttributrNode(doc,"附属","附属");
            main_para.appendChild(attribute_para);

        for(auto item:it.attached_contidition_)
        {
            int i=0;
            //QString attribute_para=tr("附属")+QString::number(i);
            QString num_name=item.num_name;
            QString subFcParaName=item.subFcParaName;
            double workMin=item.workMin;
            double workMax=item.workMax;

            auto at= createAttributrNode(doc,num_name,num_name);
            at.appendChild(createNode(doc,subFcParaName,subFcParaName));
            at.appendChild(createNode(doc,workMin,"workMin"));
            at.appendChild(createNode(doc,workMax,"workMax"));

           attribute_para.appendChild(at);
            i++;
        }

        }
    }

}
/**
    * @brief 创建属性节点
    * @param
    * @param
    */
QDomElement MainWindow::createAttributrNode(QDomDocument &doc,QString attribute_name,QString node_name)
{
 QDomElement it = doc.createElement(node_name);
     it.setAttribute(node_name,attribute_name);


    return it;
}

/**
    * @brief 创建节点
    * @param
    * @param
    */
QDomElement MainWindow::createNode(QDomDocument &doc,QString value,QString node_name)
{
 QDomElement it = doc.createElement(node_name);
    QDomText text_2 = doc.createTextNode(value);
    it.appendChild(text_2);

    return it;
}

/**
    * @brief 创建节点
    * @param
    * @param
    */
QDomElement MainWindow::createNode(QDomDocument &doc,double value,QString node_name)
{
 QDomElement it = doc.createElement(node_name);
    QDomText text_2 = doc.createTextNode(QString::number(value));
    it.appendChild(text_2);

    return it;
}


10-08 11:25