2022-11-17 08:26:05 +00:00
|
|
|
|
#include "xmlconfig.h"
|
|
|
|
|
|
|
|
|
|
#include <QFile>
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
|
|
using namespace Config;
|
|
|
|
|
|
2023-02-25 07:19:27 +00:00
|
|
|
|
class Impl_ParseException : public ParseException
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
Impl_ParseException(const QString &title, const QString &reason)
|
|
|
|
|
: reason_store(reason), title_store(title){}
|
|
|
|
|
virtual ~Impl_ParseException() = default;
|
|
|
|
|
// exception interface
|
|
|
|
|
public:
|
|
|
|
|
virtual const char *what() const override{
|
|
|
|
|
return reason_store.toLocal8Bit();}
|
|
|
|
|
|
|
|
|
|
// ParseException interface
|
|
|
|
|
public:
|
|
|
|
|
virtual QString reason() const override{ return reason_store;}
|
|
|
|
|
virtual QString title() const override{ return title_store;}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
QString reason_store;
|
|
|
|
|
QString title_store;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
XMLConfig::XMLConfig(QObject *parent)
|
|
|
|
|
: Configration(parent)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-25 07:19:27 +00:00
|
|
|
|
void XMLConfig::loadFile(const QString &path)
|
2022-11-17 08:26:05 +00:00
|
|
|
|
{
|
|
|
|
|
file_path = path;
|
|
|
|
|
QFile config(path);
|
|
|
|
|
if(!config.exists()){
|
2023-02-25 07:19:27 +00:00
|
|
|
|
if(!config.open(QIODevice::WriteOnly|QIODevice::Text))
|
|
|
|
|
throw new Impl_ParseException("解析错误", QString("指定路径无法创建配置文件:%1").arg(path));
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
QTextStream tout(&config);
|
|
|
|
|
tout << "<?xml version='1.0'?>" << endl;
|
|
|
|
|
tout << "<config />" << endl;
|
|
|
|
|
|
|
|
|
|
tout.flush();
|
|
|
|
|
config.flush();
|
|
|
|
|
config.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-02-25 07:19:27 +00:00
|
|
|
|
if(!config.open(QIODevice::Text|QIODevice::ReadOnly))
|
|
|
|
|
throw new Impl_ParseException("解析错误", QString("指定路径:%1,配置文件无法打开").arg(path));
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
QString err_str; int err_row, err_col;
|
2023-02-25 09:44:18 +00:00
|
|
|
|
if(!doc_ins.setContent(&config, false, &err_str, &err_row, &err_col))
|
2023-02-25 07:19:27 +00:00
|
|
|
|
throw new Impl_ParseException("解析错误", QString("指定配置文件:%1,row:%2,col:%3,格式错误。").arg(err_col).arg(err_row).arg(err_col));
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QDir XMLConfig::currentDir() const
|
|
|
|
|
{
|
|
|
|
|
return QFileInfo(file_path).dir();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLConfig::save() const
|
|
|
|
|
{
|
|
|
|
|
QFile fout(this->file_path);
|
2023-02-25 07:19:27 +00:00
|
|
|
|
if(!fout.open(QIODevice::WriteOnly | QIODevice::Text))
|
|
|
|
|
throw new Impl_ParseException("配置文件保存错误", QString("指定配置文件%1保存过程中,无法打开").arg(file_path));
|
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
QTextStream tout(&fout);
|
|
|
|
|
tout << this->doc_ins.toString(4);
|
|
|
|
|
tout.flush();
|
|
|
|
|
fout.flush();
|
|
|
|
|
fout.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLConfig::deleteX(const QList<QString> &path)
|
|
|
|
|
{
|
|
|
|
|
auto elm = local_exists_elm(doc_ins.documentElement(), path);
|
|
|
|
|
if(elm.isNull())
|
|
|
|
|
return;
|
2023-02-25 07:19:27 +00:00
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
elm.parentNode().removeChild(elm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLConfig::setConfig(const QList<QString> &path, const QString &value)
|
|
|
|
|
{
|
|
|
|
|
auto doc = doc_ins.documentElement();
|
|
|
|
|
auto elm = rebuild_exists_elms(doc, path);
|
2023-02-25 07:19:27 +00:00
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
elm.setAttribute("value", value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString XMLConfig::getConfig(const QList<QString> &path) const
|
|
|
|
|
{
|
|
|
|
|
auto elm = local_exists_elm(doc_ins.documentElement(), path);
|
|
|
|
|
if(elm.isNull())
|
|
|
|
|
return "";
|
2023-02-25 07:19:27 +00:00
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
return elm.attribute("value");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLConfig::setList(const QList<QString> &path, const QList<QString> &list)
|
|
|
|
|
{
|
|
|
|
|
auto root = doc_ins.documentElement();
|
|
|
|
|
auto telm = rebuild_exists_elms(root, path);
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto childs = telm.childNodes();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-25 07:19:27 +00:00
|
|
|
|
for(auto idx= 0; idx<childs.count(); ++idx){
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto node = childs.at(idx);
|
2023-02-25 07:19:27 +00:00
|
|
|
|
|
2022-11-22 03:42:48 +00:00
|
|
|
|
if(node.isElement() && node.toElement().tagName() == "list")
|
2023-02-25 07:19:27 +00:00
|
|
|
|
telm.removeChild(node);
|
2022-11-22 03:42:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(auto &it : list){
|
2022-11-17 08:26:05 +00:00
|
|
|
|
auto nelm = doc_ins.createElement("list");
|
|
|
|
|
nelm.setAttribute("value", it);
|
|
|
|
|
telm.appendChild(nelm);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<QString> XMLConfig::getList(const QList<QString> &path) const
|
|
|
|
|
{
|
|
|
|
|
auto elm = local_exists_elm(doc_ins.documentElement(), path);
|
|
|
|
|
|
|
|
|
|
QList<QString> rets;
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto childs = elm.childNodes();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
for(auto idx=0; idx<childs.count(); ++idx){
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto node = childs.at(idx);
|
|
|
|
|
|
|
|
|
|
if(node.isElement() && node.toElement().tagName() == "list"){
|
|
|
|
|
rets << node.toElement().attribute("value");
|
|
|
|
|
}
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rets;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLConfig::setMap(const QList<QString> &path, const QHash<QString, QString> &map)
|
|
|
|
|
{
|
|
|
|
|
auto root = doc_ins.documentElement();
|
|
|
|
|
auto telm = rebuild_exists_elms(root, path);
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto childs = telm.childNodes();
|
|
|
|
|
|
|
|
|
|
QList<QDomNode> nodes;
|
|
|
|
|
for(auto idx=0; idx<childs.count(); ++idx){
|
|
|
|
|
auto child = childs.at(idx);
|
|
|
|
|
if(child.isElement() && child.toElement().tagName() == "map")
|
2023-02-25 07:19:27 +00:00
|
|
|
|
telm.removeChild(child);
|
2022-11-22 03:42:48 +00:00
|
|
|
|
}
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
for(auto &key : map.keys()){
|
|
|
|
|
auto nelm = doc_ins.createElement("map");
|
|
|
|
|
nelm.setAttribute("key", key);
|
|
|
|
|
nelm.setAttribute("value", map[key]);
|
|
|
|
|
telm.appendChild(nelm);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QHash<QString, QString> XMLConfig::getMap(const QList<QString> &path) const
|
|
|
|
|
{
|
|
|
|
|
auto elm = local_exists_elm(doc_ins.documentElement(), path);
|
|
|
|
|
|
|
|
|
|
QHash<QString, QString> rets;
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto childs = elm.childNodes();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
for(auto idx=0; idx<childs.count(); ++idx){
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto node = childs.at(idx);
|
|
|
|
|
if(node.isElement()){
|
|
|
|
|
auto elm = node.toElement();
|
|
|
|
|
|
|
|
|
|
if(elm.tagName() == "map")
|
|
|
|
|
rets[elm.attribute("key")] = elm.attribute("value");
|
|
|
|
|
}
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rets;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QDomElement XMLConfig::local_exists_elm(const QDomElement &elm_base, const QList<QString> &path, int level) const
|
|
|
|
|
{
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto child = elm_base.childNodes();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
for(auto idx=0; idx<child.count(); ++idx){
|
|
|
|
|
auto ins = child.at(idx);
|
|
|
|
|
if(ins.isElement()){
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto elm = ins.toElement();
|
|
|
|
|
if(elm.tagName() == "path" && elm.attribute("key") == path[level]){
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2022-11-22 03:42:48 +00:00
|
|
|
|
// 完成过滤,进行匹配
|
2022-11-17 08:26:05 +00:00
|
|
|
|
if(level == path.size()-1)
|
2022-11-22 03:42:48 +00:00
|
|
|
|
return elm;
|
|
|
|
|
|
|
|
|
|
return local_exists_elm(elm, path, level+1);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return QDomElement();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QDomElement XMLConfig::rebuild_exists_elms(QDomElement &elm_base, const QList<QString> &path, int level)
|
|
|
|
|
{
|
2022-11-22 03:42:48 +00:00
|
|
|
|
auto childnodes = elm_base.childNodes();
|
|
|
|
|
for(auto idx=0; idx<childnodes.count(); ++idx){
|
|
|
|
|
auto ins = childnodes.at(idx);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
if(ins.isElement()){
|
|
|
|
|
auto eins = ins.toElement();
|
2022-11-22 03:42:48 +00:00
|
|
|
|
if(eins.tagName() == "path" && eins.attribute("key") == path[level]){
|
|
|
|
|
// 完成过滤,进行匹配
|
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
if(level == path.size() - 1)
|
|
|
|
|
return eins;
|
2022-11-22 03:42:48 +00:00
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
return rebuild_exists_elms(eins, path, level+1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
auto nelm = elm_base.ownerDocument().createElement("path");
|
|
|
|
|
nelm.setAttribute("key", path[level]);
|
|
|
|
|
elm_base.appendChild(nelm);
|
|
|
|
|
|
|
|
|
|
if(level < path.count() -1)
|
|
|
|
|
return rebuild_exists_elms(nelm, path, level+1);
|
|
|
|
|
return nelm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|