本机系统配置:ThinkPadT570、Windows10、QT5.12.2(QtCreater4.8.2)
我建立的qt工程名为EditPic
需要解析的配置文件名为test.config,放在工程目录下
配置文件内容如下:
<?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文件中需要添加如下代码,便于后面使用QDomDocument方法。
QT += xml
工程中添加一个c++类,名为ConfigFileManager,继承自QObject,头文件内容如下:
#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
源文件代码如下:
#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;
}
在工程主线程中如下调用上述类:
ConfigFileManager cfg;
bool bret = cfg.ParseConfigFile();