您的位置:首页 > 编程语言 > Qt开发

Qt的XML封装类QXmlWrapper,实现XML文件的创建、删除以及元素节点的增加、删除、修改与查找等。

2017-12-15 11:01 951 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013956630/article/details/78810628

最近使用Qt开发软件,需要用到xml用于保存软件配置信息,发现Qt的XML使用起来不是很方便,所以基于QDomDocument类进一步封装了QXmlWrapper类。

注:博主用的Qt版本是4.8.5,开发环境是Qt Creator。


一、XML文件的创建、删除与重命名

1.XML文件的创建


bool QXmlWrapper::CreateXmlFile(const QString &_fileName,
const QString &_rootName,
const QString &_version,
const QString &_encoding,
const QString &_standalone)
{
QFile file(_fileName);

// 只写方式打开,并清空以前的信息
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return false;

QDomDocument doc;
QDomProcessingInstruction instruction;  //添加处理指令(声明)
QString data;
data = "version=\"" + _version + "\" encoding=\"" + _encoding + "\" standalone=\"" + _standalone + "\"";
instruction = doc.createProcessingInstruction("xml", data);
doc.appendChild(instruction);
QDomElement root = doc.createElement(_rootName);
doc.appendChild(root); //添加根元素

QTextStream out(&file);
doc.save(out,4); // 将文档保存到文件,4为子元素缩进字符数
file.close();
return true;
}



其中_fileName为文件名,_rootName为根节点名。


2.XML文件的删除

bool QXmlWrapper::DeleteXmlFile(const QString &_fileName)
{
if (_fileName.isEmpty())
{
return false;
}

QFile file(_fileName);
if(!file.setPermissions(QFile::WriteOwner)) // 修改文件属性
return false;
if(!QFile::remove(_fileName)) // 删除文件
return false;

return true;
}
若文件为只读属性,需要修改文件属性。


3.XML文件的重命名

bool QXmlWrapper::RenameXmlFile(const QString &_fileName,
const QString &_newName)
{
return QFile::rename(_fileName, _newName);
}


二、元素节点的操作

无论查询节点、删除节点、修改节点和增加节点,其实都离不开一个函数,就是根据节点名获取相关节点。那么我们就先实现一个根据节点名获取节点的函数:

1.根据节点名获取节点

bool QXmlWrapper::GetNodeByName(QDomElement &_rootEle,
const QString &_nodeName,
QDomElement &_node)
{
if(_nodeName == _rootEle.tagName()) // 若为根节点,则返回
{
_node = _rootEle;
return true;
}

QDomElement ele = _rootEle;  //返回根元素

for (ele = _rootEle.firstChildElement(); ele.isElement(); ele = ele.nextSiblingElement())
{
//递归处理子节点,获取节点
if(GetNodeByName(ele, _nodeName, _node))
return true;
}
return false;
}

其中,_rootEle为根节点,_nodeName为待查询的节点名,_node即为查找到的节点。

首先,根据节点名判断是否为根节点,若是则返回true,若不是则查询所有子节点是否符合条件;

然后,若还未查到则递归查询,直到满足为止。

若所有节点都不符合条件,则返回false。


2.新增元素节点

    这里分2种情况:有文本无属性的节点、既有文本又有属性的节点。

先说第一种,有文本无属性的节点:

首先根据XML文件名读取文件内容并存入QDomDocument对象Doc;

然后根据Doc获取根节点QDomElement rootEle = doc.documentElement();

再利用上面的提到的GetNodeByName获取该节点的父节点;

最后利用QDomElement的appChild方法插入该子节点。

bool QXmlWrapper::AddNode_Text(const QString &_fileName,
const QString &_parentNodeName,
const QString &_nodeName,
const QString &_nodeText)
{
if (_fileName.isEmpty()) // 文件名为空
{
return false;
}

// 新建QDomDocument类对象,它代表一个XML文档
QDomDocument doc;
// 建立指向“_fileName”文件的QFile对象
QFile file(_fileName);
// 以只读方式打开
if (!file.open(QIODevice::ReadOnly))
return false;
// 将文件内容读到doc中
if (!doc.setContent(&file))
{
file.close();
return false;
}
// 关闭文件
file.close();

QDomElement rootEle = doc.documentElement();  //返回根元素
QDomElement parentNode;
GetNodeByName(rootEle, _parentNodeName, parentNode);

// 添加元素及其文本
QDomElement childEle = doc.createElement(_nodeName);
QDomText text;
text = doc.createTextNode(_nodeText);
childEle.appendChild(text);
parentNode.appendChild(childEle);

if(!file.open(QFile::WriteOnly|QFile::Truncate)) //先读进来,再重写,如果不用truncate就是在后面追加内容,就无效了
return false;
//输出到文件
QTextStream out(&file);
doc.save(out,4); // 将文档保存到文件,4为子元素缩进字符数
file.close();

return true;
}


3.删除元素节点

与新增元素节点类似,只是查找的不是父节点而是该节点本身,最后利用QDomElement的removeChild()方法删除该节点。

// 假如是根节点
if (rootEle == nodeEle)
//doc.removeChild(rootEle);
return false;

// 假如是其它节点
if (nodeEle.isElement())
{
QDomNode parentEle = nodeEle.parentNode();

if (parentEle.isElement())
parentEle.removeChild(nodeEle);
else
return false;
}


4.修改元素节点

这里也分2种情况:修改节点文本与修改节点属性。
与之前删除节点类似,找到节点后,不能直接修改该节点文本,需要利用新的文本替换该节点文本,具体操作如下:

if(nodeEle.isElement())
{
QDomNode oldnode = nodeEle.firstChild();     //标签之间的内容作为节点的子节点出现,得到原来的子节点
nodeEle.firstChild().setNodeValue(_nodeText);   //用提供的value值来设置子节点的内容
QDomNode newnode = nodeEle.firstChild();     //值修改过后
nodeEle.replaceChild(newnode,oldnode);      //调用节点的replaceChild方法实现修改功能
}

5.查询元素节点

这里也分2种情况:查询节点文本与查询节点属性。
与之前删除节点类似,找到节点后,分别利用QDomElement的text()与attribute()方法获取节点的文本与属性具体操作如下:

if(nodeEle.isElement())    {
QDomNode oldnode = nodeEle.firstChild();     //标签之间的内容作为节点的子节点出现,得到原来的子节点
nodeEle.firstChild().setNodeValue(_nodeText);   //用提供的value值来设置子节点的内容
QDomNode newnode = nodeEle.firstChild();     //值修改过后
nodeEle.replaceChild(newnode,oldnode);      //调用节点的replaceChild方法实现修改功能
}

另还有QXmlWrapper实现了查询所有子节点的文本等功能。想要获取完成的代码可以查看这里点击打开链接









阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐