Qt achieve xml file read resolved by QDomDocument

This system configuration: ThinkPadT570, Windows10, QT5.12.2 (QtCreater4.8.2 )
I created qt project called EditPic
need to parse the configuration file named test.config, placed in the project directory
configuration file as follows:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<ROOT version="1.0alpha" time="20190417">
  <BRANCH_LEVEL1 name="BranchLV1_1" AlgorithmID="1" nickname="一级分支1" index="1" visible="on" invokeOrder="1,2,3">
    <BRANCH_LEVEL2 name="BranchLV2_1" SubAlgoID ="1" nickname="二级分支1" index="1"  visible="off">
      <param name="param1" valueRange="0,10" nickname="参数1" index="1" valuetype="int" value="1" visible="off"/>
    </BRANCH_LEVEL2>
    <BRANCH_LEVEL2 name="BranchLV2_2" SubAlgoID ="2" nickname="二级分支2" index="2"  visible="off">
      <param name="param2" valueRange="0,10" nickname="参数2" index="1"  valuetype="int" value="1" visible="off"/>
    </BRANCH_LEVEL2>
  </BRANCH_LEVEL1>
  <BRANCH_LEVEL1 name="BranchLV1_2" AlgorithmID="3" nickname="一级分支2" index="3"  visible="on" invokeOrder="1,2,3,4">
    <BRANCH_LEVEL2 name="BranchLV2_1" SubAlgoID ="1" nickname="二级分支1" index="1"  visible="on">
      <param name="param1" valueRange="0,10" nickname="参数1" index="1"  valuetype="int" value="1" visible="on" />
    </BRANCH_LEVEL2>
    <BRANCH_LEVEL2 name="BranchLV2_2" SubAlgoID ="2" nickname="二级分支2" index="2"  visible="on">
      <param name="param2" valueRange="0,10" nickname="参数2" index="1"  valuetype="int" value="1" visible="on" />
    </BRANCH_LEVEL2>
  </BRANCH_LEVEL1>
</ROOT>
</configuration>

EditPic.pro project file need to add the following code to facilitate later with QDomDocument method.

QT       += xml

Project to add a c ++ class called ConfigFileManager, inherited from QObject, the header file as follows:

#ifndef CONFIGFILEMANAGER_H
#define CONFIGFILEMANAGER_H
#include <QObject>
#include <QString>
#include <QFileInfo>
#include <QtXml/QDomDocument>
#include <QDebug>
#include <QMap>
#include <QCoreApplication>
#include <QDir>
#include <QSettings>
#include <QVector>
struct PARAM//参数节点
{
    int                 m_nIndex;//参数ID
    QString             m_sName;//参数名
    QString             m_sNickname;//参数中文名
    QString             m_sValueType;//参数类型
    int                 m_nValueRange[2];//int类型的参数范围
    float               m_fValueRange[2];//float类型的参数范围
    QVector<int>        m_vIntValue;//int类型的参数容器
    QVector<float>      m_vFloatValue;//float类型的参数容器
    QString             m_sStringValue;//string类型的参数、或者enum类型的参数、或bool类型的参数
    QStringList         m_slistEnumValues;//enum类型的参数值列表
    bool                m_bVisible;//参数是否显示
    PARAM():m_nIndex(0),
        m_sName(""),
        m_sNickname(""),
        m_sValueType(""),
        m_bVisible(true)
    {
        m_nValueRange[0] = 0;
        m_nValueRange[1] = 0;
        m_fValueRange[0] = 0;
        m_fValueRange[1] = 0;
        m_sStringValue = "";
        if(!m_slistEnumValues.empty())
        {
            m_slistEnumValues.clear();
        }
    }
};
struct BRANCH_LEVEL2//二级分支节点
{
    int                     m_nIndex;
    QString                 m_sName;
    QString                 m_sNickname;
    int                     m_nAlgoId;
    bool                    m_bVisible;
    QMap<int,PARAM>         m_mapParams;
};
struct BRANCH_LEVEL1//一级分支节点
{
    int                     m_nIndex;
    QString                 m_sName;
    QString                 m_sNickname;
    int                     m_nAlgoId;
    bool                    m_bVisible;
    QVector<int>            m_vInvokeOrder;
    QMap<int,BRANCH_LEVEL2>       m_mapBranchLevel2;
};
struct ROOT//根节点
{
    QString                 m_sVersion;
    QString                 m_sTime;
    QMap<int,BRANCH_LEVEL1>     m_mapBranchLevel1;
};
class ConfigFileManager : public QObject
{
        Q_OBJECT
public:
    ConfigFileManager();
    bool            ParseConfigFile();
private:
    void            ParseROOT(QDomNode* node);
    void            ParseBRANCH_LEVEL1(QDomNode* node, QMap<int, BRANCH_LEVEL1> &mapBranchLevel1);
    void            ParseBRANCH_LEVEL2(QDomNode *node, QMap<int, BRANCH_LEVEL2> &mapBranchLevel2);
    void            ParseParameters(QDomNode *node, QMap<int,PARAM> &mapParam);
    QVector<int>    SplitXmlStringInt(QString xmlText);
    QVector<float>  SplitXmlStringFloat(QString xmlText);
private:
    ROOT                m_tRoot;
};

#endif // CONFIGFILEMANAGER_H

Source code is as follows:

#include "configfilemanager.h" 
ConfigFileManager::ConfigFileManager()
{    
}
bool ConfigFileManager::ParseConfigFile()//读取test.config文件并获取根节点
{
    QString strAlgolistPath;
#if defined(Q_OS_LINUX)
    strAlgolistPath = qApp->applicationDirPath() + "/../EditPic/test.config" ;//in linux
#else
    strAlgolistPath = qApp->applicationDirPath() + "/../../EditPic/test.config" ;//in windows,我的工程名为EditPic
#endif
    QFile file(strAlgolistPath);
    if (!file.open(QFile::ReadOnly))
    {
        return false;
    }
    QString errorStr;
    int errorLine;
    int errorColumn;
    QDomDocument qDomAlgoList;
    if (!qDomAlgoList.setContent(&file, false, &errorStr, &errorLine,&errorColumn))
    {
        return false;
    }
    QDomElement root = qDomAlgoList.documentElement();
    QDomNode child = root.firstChild();
    if (!child.isNull())
    {
        if(child.toElement().tagName() == "ROOT")
        {
            ParseROOT(&child);
        }
    }
    file.close();
    return true;
}

void ConfigFileManager::ParseROOT(QDomNode *node)//解析根节点
{
    m_tRoot.m_sVersion = node->toElement().attribute("version");
    m_tRoot.m_sTime = node->toElement().attribute("time");
    ParseBRANCH_LEVEL1(node,m_tRoot.m_mapBranchLevel1);
}

void ConfigFileManager::ParseBRANCH_LEVEL1(QDomNode *node, QMap<int, BRANCH_LEVEL1> &mapBranchLevel1)//解析一级分支
{
    QDomNode childnode = node->toElement().firstChild();
    while(!childnode.isNull())
    {
        if(childnode.toElement().tagName() == "BRANCH_LEVEL1")
        {
            BRANCH_LEVEL1 BranchLevel1;
            BranchLevel1.m_sName = childnode.toElement().attribute("name");
            BranchLevel1.m_nAlgoId = childnode.toElement().attribute("AlgorithmID").toInt();
            BranchLevel1.m_sNickname = childnode.toElement().attribute("nickname");
            BranchLevel1.m_nIndex = childnode.toElement().attribute("index").toInt();
            QString sVisible = childnode.toElement().attribute("visible");
            if(sVisible=="on")
            {
                BranchLevel1.m_bVisible = true;
            }
            else
            {
                BranchLevel1.m_bVisible = false;
            }
            QString sInvokerOrder = childnode.toElement().attribute("invokeOrder");
            BranchLevel1.m_vInvokeOrder = SplitXmlStringInt(sInvokerOrder);
            ParseBRANCH_LEVEL2(&childnode,BranchLevel1.m_mapBranchLevel2);
            mapBranchLevel1.insert(BranchLevel1.m_nIndex,BranchLevel1);
        }
        childnode = childnode.nextSibling();
    }
}

void ConfigFileManager::ParseBRANCH_LEVEL2(QDomNode *node, QMap<int, BRANCH_LEVEL2> &mapBranchLevel2)//解析二级分支
{
    QDomNode childnode = node->toElement().firstChild();
    while(!childnode.isNull())
    {
        if(childnode.toElement().tagName() == "BRANCH_LEVEL2")
        {
            BRANCH_LEVEL2 BranchLevel2;
            BranchLevel2.m_sName = childnode.toElement().attribute("name");
            BranchLevel2.m_nAlgoId = childnode.toElement().attribute("SubAlgoID").toInt();
            BranchLevel2.m_sNickname = childnode.toElement().attribute("nickname");
            BranchLevel2.m_nIndex = childnode.toElement().attribute("index").toInt();
            QString sVisible = childnode.toElement().attribute("visible");
            if(sVisible=="on")
            {
                BranchLevel2.m_bVisible = true;
            }
            else
            {
                BranchLevel2.m_bVisible = false;
            }
            ParseParameters(&childnode,BranchLevel2.m_mapParams);
            mapBranchLevel2.insert(BranchLevel2.m_nIndex,BranchLevel2);
        }
        childnode = childnode.nextSibling();
    }
}
void ConfigFileManager::ParseParameters(QDomNode *node, QMap<int,PARAM> &mapParam)//解析参数
{

    QDomNode childnode = node->toElement().firstChild();
    while(!childnode.isNull())
    {
        if(childnode.toElement().tagName() == "param")
        {
            PARAM Parameter;
            Parameter.m_nIndex = childnode.toElement().attribute("index").toInt();
            Parameter.m_sName = childnode.toElement().attribute("name");
            Parameter.m_sNickname = childnode.toElement().attribute("nickname");
            Parameter.m_sValueType = childnode.toElement().attribute("valuetype");
            QString Value,RangeValue;
            if(Parameter.m_sValueType == "int")
            {
                Value = childnode.toElement().attribute("value");
                Parameter.m_vIntValue = SplitXmlStringInt(Value);
                RangeValue = childnode.toElement().attribute("valueRange");
                QStringList list = RangeValue.split(',');
                if(2 == list.size())
                {
                    Parameter.m_nValueRange[0] = list.at(0).toInt();
                    Parameter.m_nValueRange[1] = list.at(1).toInt();
                }
            }
            else if(Parameter.m_sValueType == "float")
            {
                Value = childnode.toElement().attribute("value");
                Parameter.m_vFloatValue = SplitXmlStringFloat(Value);
                RangeValue = childnode.toElement().attribute("valueRange");
                QStringList list = RangeValue.split(',');
                if(2 == list.size())
                {
                    Parameter.m_fValueRange[0] = list.at(0).toInt();
                    Parameter.m_fValueRange[1] = list.at(1).toInt();
                }
            }
            else if(Parameter.m_sValueType == "string")
            {
                Parameter.m_sStringValue = childnode.toElement().attribute("value");
            }
            else if((Parameter.m_sValueType == "enum")||((Parameter.m_sValueType == "bool")))
            {
                Parameter.m_sStringValue = childnode.toElement().attribute("value");
                QString valuelist = childnode.toElement().attribute("valueList");
                Parameter.m_slistEnumValues = valuelist.split(",");
                RangeValue = childnode.toElement().attribute("valueRange");
                QStringList list = RangeValue.split(',');
                if(2 == list.size())
                {
                    Parameter.m_nValueRange[0] = list.at(0).toInt();
                    Parameter.m_nValueRange[1] = list.at(1).toInt();
                }
            }
            QString sVisible = childnode.toElement().attribute("visible");
            if(sVisible=="on")
            {
                Parameter.m_bVisible = true;
            }
            else
            {
                Parameter.m_bVisible = false;
            }
            mapParam.insert(Parameter.m_nIndex,Parameter);
        }
        childnode = childnode.nextSibling();
    }
}
QVector<int> ConfigFileManager::SplitXmlStringInt(QString xmlText)//将QString按逗号分割,并转为int类型,存放到QVector<int>
{
    QVector<int> vParam;
    QString value;
    QStringList list = xmlText.split(',');
    for (int i = 0; i < list.size(); ++i)
    {
        value = list.at(i);
        vParam.push_back(value.toInt());
    }
    return vParam;
}
QVector<float> ConfigFileManager::SplitXmlStringFloat(QString xmlText)//将QString按逗号分割,并转为float类型,存放到QVector<float>
{
    QVector<float> vParam;
    QString value;
    QStringList list = xmlText.split(',');
    for (int i = 0; i < list.size(); ++i)
    {
        value = list.at(i);
        vParam.push_back(value.toFloat());
    }
    return vParam;
}

In the project the main thread calls the above categories are as follows:

ConfigFileManager cfg;
bool bret = cfg.ParseConfigFile();

Guess you like

Origin blog.csdn.net/weixin_43935474/article/details/89608801