博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt之QDomDocument操作xml文件-模拟ini文件存储
阅读量:6904 次
发布时间:2019-06-27

本文共 5185 字,大约阅读时间需要 17 分钟。

一、背景

  不得不说Qt是一个很强大的类库,不管是做项目还是做产品,Qt自身封装的东西就已经非常全面了,我们今天的这篇文章就是模拟了Qt读写ini文件的一个操作,当然是由于一些外力原因,我们决定自己来完善下这个功能。好的,那么现在就让我们隆重的请出今天的主角--QSettings。这个类能干嘛呢? 答案就是:读写注册表或者读写ini文件,这对于我们做应用程序时记录一些可持久化数据非常有用。

二、QSettings访问ini文件

  QSettings访问ini文件相对来说比较简单,我们只需要构造一个QSettings对象,传入文件名称和文件存储格式即可,如图1所示。但同时QSettings也有一些局限,如下:

1、(QTBUG15543、QTBUG19552)
2、QSettings的key不能为中文
3、当在一个嵌套作用域多次构造QSettings时并设置了编码,此时访问文件设置的编码会失效
  由于QSettings有一些限制,也就引出了我们这篇文章的内容,使用xml模拟ini文件,下面我们主要分析下怎么使用xml文件模拟ini文件,需要的接口并不多,读、写、新增和删除。

图1 QSettings读写ini

三、xml文件读写

  读写xml文件的方式有很多,Qt提供了2种比较常用的方式:DOM和SAX,详情可以参看:。初次之外C++还提供了几种库用于操作xml文件,比如:libxml2、tinyXml等。

此处我们模拟的是QSettings读写ini文件,因此使用Qt自带的DOM方式读写xml,操作起来相对容易。

  如图2所示,是我们xml文件操作类的几个重要接口和成员,前边4个公有接口分别对应。读、写、新增和删除;成员变量m_filePath表示加载的xml文件路径,m_mItemMap表示2级的ini文件结构

图2 xml文件操作头文件

1、读xml文件

1 void xmlOperate::readXml( const QString & filePath ) 2 { 3     if(filePath.isEmpty()) 4         return; 5  6     QFile file(filePath); 7     if(file.open(QFile::ReadOnly | QFile::Text) == false) 8         return; 9 10     QDomDocument domDocument;11     QString error;12     int row = 0, column = 0;13     if(domDocument.setContent(&file, false, &error, &row, &column) == false)14         return file.close();15 16     if(domDocument.isNull()) 17         return file.close();18 19     m_mItemMap.clear();20 21     QDomElement rootElement = domDocument.documentElement();22     QDomNodeList groupList = rootElement.childNodes();23     for(int i = 0; i < groupList.count(); ++i)24     {25         QDomNode groupNode = groupList.item(i);26         QDomElement groupElement = groupNode.toElement();27         QString groupName = groupElement.attribute("name");28 29         QMap
items;30 QDomNodeList itemList = groupElement.childNodes();31 for (int j = 0; j < itemList.count(); ++j)32 {33 QDomNode itemNode = itemList.item(j);34 QDomElement itemElement = itemNode.toElement();35 QString itemName = itemElement.attribute("name");36 QString itemText = itemElement.text();37 38 if (itemName.isEmpty())39 {40 items[QString::number(j)] = itemText;41 }42 else43 {44 items[itemName] = itemText;45 }46 }47 m_mItemMap[groupName] = items;48 }49 50 file.close();51 52 qDebug() << m_mItemMap;53 }
View Code

2、保存xml文件

1 void xmlOperate::writeXml(const QString & filePath) 2 { 3     QDomDocument domDocument; 4     QString strHeader( "version=\"1.0\" encoding=\"UTF-8\"" ); 5     domDocument.appendChild( domDocument.createProcessingInstruction("xml", strHeader) ); 6  7     QDomElement root = domDocument.createElement("groups"); 8     domDocument.appendChild(root); 9 10     for(auto iter = m_mItemMap.begin(); iter != m_mItemMap.end(); ++iter)11     {12         QDomElement groupNode = domDocument.createElement("group");13         groupNode.setAttribute("name", iter.key());14 15         QMap
items = iter.value();16 for (auto iter2 = items.begin(); iter2 != items.end(); ++iter2)17 {18 QString key = iter2.key();19 QString value = iter2.value();20 21 QDomElement itemNode = domDocument.createElement("item");22 itemNode.setAttribute("name", key);23 24 QDomText textNode = domDocument.createTextNode(value);25 itemNode.appendChild(textNode);26 27 groupNode.appendChild(itemNode);28 }29 root.appendChild(groupNode);30 }31 32 QFile file(filePath);33 if(file.open(QFile::WriteOnly | QFile::Text))34 {35 QTextStream out(&file);36 domDocument.save(out, 4);37 file.close();38 }39 qDebug() << m_mItemMap;40 }
View Code

3、插入项

1 bool xmlOperate::addItem( const QString & value, const QString & group, const QString & key ) 2 { 3     if (value.isEmpty() || group.isEmpty()) 4     { 5         return false; 6     } 7  8     if (key.isEmpty()) 9     {10         int count = m_mItemMap[group].size();11         m_mItemMap[group][QString::number(count)] = value;12     }13     else14     {15         m_mItemMap[group][key] = value;16     }17 18     writeXml(m_filePath);19 20     return true;21 }

4、删除项

1 bool xmlOperate::removeItem( const QString & value, const QString & group, const QString & key /*= ""*/ ) 2 { 3     if (value.isEmpty() || group.isEmpty()) 4     { 5         return false; 6     } 7  8     if (key.isEmpty()) 9     {10         int count = m_mItemMap[group].size();11         if (count == 0)12         {13             return false;14         }15         16         auto iter = m_mItemMap[group].begin();17         while (iter != m_mItemMap[group].end())18         {19             if (iter.value() == value)20             {21                 iter = m_mItemMap[group].erase(iter);22             }23             else24             {25                 ++iter; 26             }27         }28     }29     else30     {31         m_mItemMap[group].remove(key);32     }33 34     writeXml(m_filePath);35 36     return true;37 }

四、示例程序下载

如图3是测试代码生成的测试结果,group相当于ini文件中的一个分组,item表示分组中的一项

图3 测试程序结果

 

转载地址:http://dpldl.baihongyu.com/

你可能感兴趣的文章
常用命令 tcl & shell
查看>>
关于MFC布局
查看>>
JS复习
查看>>
wx模拟鼠标事件
查看>>
JavaScript高级程序设计--对象,数组(栈方法,队列方法,重排序方法,迭代方法)...
查看>>
VS环境下的makefile编译
查看>>
VS2010下测试程序性能瓶颈
查看>>
微信小程序获取Access_token和页面URL生成小程序码或二维码
查看>>
压缩字符流和字节流和全站压缩过滤器
查看>>
prototype 用法
查看>>
第一周web作业2:roadmap
查看>>
BindingMemberInfo
查看>>
1231 实验四 递归下降语法分析程序设计
查看>>
作用域
查看>>
JavaScript-indexOf函数
查看>>
06 Django URL name详解
查看>>
day04 - 02 linux简单的操作命令
查看>>
pve之命令
查看>>
更新Xcode的版本,发现添加的appleID是之前的人的,现在没有其密码!现在换成新的appleID...
查看>>
架构师技术之-数据库及存储业务集群高可用分布式专题
查看>>