[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档
[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档
使用DOM创建和操作XML文档
版权声明
该文章原创于作者yafeilinux,转载请注明出处!
导语
在上一节中我们用手写的方法建立了一个XML文档,并且用DOM的方法对其进行了读取。现在我们使用代码来创建那个XML文档,并且对它实现查找、更新、插入等操作。
环境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2
目录
一、创建文档
二、读取文档
三、添加节点
四、查找、删除、更新操作
正文
一、创建文档
1.新建Qt Gui应用,项目名称为myDom_2,基类为QMainWindow,类名为MainWindow。
2.完成后打开myDom_2.pro,然后将第一行代码更改为:
QT += core gui xml
保存该文件。
3.双击mainwindow.ui进入设计模式,往界面上添加Push Button,Label,Line Edit,List Widget等部件,设计界面如下图所示。
4.完成后,打开mainwindow.cpp文件,先包含头文件#include <QtXml>,然后在构造函数中添加如下代码:
QFile file("my.xml");
// 只写方式打开,并清空以前的信息
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) return ;
QDomDocument doc;
QDomProcessingInstruction instruction; //添加处理指令
instruction = doc.createProcessingInstruction("xml","version=\"1.0\"encoding=\"UTF-8\"");
doc.appendChild(instruction);
QDomElement root = doc.createElement(tr("书库"));
doc.appendChild(root); //添加根元素
// 添加第一个book元素及其子元素
QDomElement book = doc.createElement(tr("图书"));
QDomAttr id = doc.createAttribute(tr("编号"));
QDomElement title = doc.createElement(tr("书名"));
QDomElement author = doc.createElement(tr("作者"));
QDomText text;
id.setValue(tr("1"));
book.setAttributeNode(id);
text = doc.createTextNode(tr("Qt"));
title.appendChild(text);
text = doc.createTextNode(tr("shiming"));
author.appendChild(text);
book.appendChild(title);
book.appendChild(author);
root.appendChild(book);
// 添加第二个book元素及其子元素
book = doc.createElement(tr("图书"));
id = doc.createAttribute(tr("编号"));
title = doc.createElement(tr("书名"));
author = doc.createElement(tr("作者"));
id.setValue(tr("2"));
book.setAttributeNode(id);
text = doc.createTextNode(tr("Linux"));
title.appendChild(text);
text = doc.createTextNode(tr("yafei"));
author.appendChild(text);
book.appendChild(title);
book.appendChild(author);
root.appendChild(book);
QTextStream out(&file);
doc.save(out,4); // 将文档保存到文件,4为子元素缩进字符数
file.close();
这里先使用QDomDocument类在内存中生成了一棵DOM树,然后调用save()函数利用QTextStream文本流将DOM树保存在了文件中。在生成DOM树时主要使用了createElement()等函数来生成各种节点,然后使用appendChild()将各个节点依次追加进去。
5.打开main.cpp文件,先包含头文件:#include <QTextCodec>,然后在main()函数第一行代码后面添加如下代码:
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
6.运行程序,可以看到在构建目录中生成了my.xml文件,可以双击查看该文件的内容,效果如下图所示。
二、读取文档
下面我们读取整个文档的内容,并显示在List Widget部件上面,这里用的就是上一节讲到的内容。我们进入“查看全部信息”按钮单击信号槽,更改如下:
void MainWindow::on_pushButton_5_clicked()
{
ui->listWidget->clear(); //先清空显示
QFile file("my.xml");
if (!file.open(QIODevice::ReadOnly)) return ;
QDomDocument doc;
if (!doc.setContent(&file))
{
file.close();
return ;
}
file.close();
//返回根节点及其子节点的元素标记名
QDomElement docElem = doc.documentElement(); //返回根元素
QDomNode n = docElem.firstChild(); //返回根节点的第一个子节点
while(!n.isNull()) //如果节点不为空
{
if (n.isElement()) //如果节点是元素
{
QDomElement e = n.toElement(); //将其转换为元素
ui->listWidget->addItem(e.tagName()
+e.attribute(tr("编号")));
QDomNodeList list = e.childNodes();
for(int i=0; i<list.count(); i++)
{
QDomNode node = list.at(i);
if(node.isElement())
ui->listWidget->addItem(" "
+node.toElement().tagName()
+" : "+node.toElement().text());
}
}
n = n.nextSibling(); //下一个兄弟节点
}
}
运行程序,效果如下图所示。
三、添加节点
1.首先在设计模式,把书名和作者标签后面的Line Edit部件的objectName分别更改为lineEdit_title和lineEdit_author。如下图所示。
2.然后进入添加按钮的单击信号槽,添加如下代码:
void MainWindow::on_pushButton_4_clicked()
{
ui->listWidget->clear(); //我们先清空显示,然后显示“无法添加!”
ui->listWidget->addItem(tr("无法添加!"));
QFile file("my.xml");
if (!file.open(QIODevice::ReadOnly)) return;
QDomDocument doc;
if (!doc.setContent(&file))
{
file.close();
return;
}
file.close();
QDomElement root = doc.documentElement();
QDomElement book = doc.createElement(tr("图书"));
QDomAttr id = doc.createAttribute(tr("编号"));
QDomElement title = doc.createElement(tr("书名"));
QDomElement author = doc.createElement(tr("作者"));
QDomText text;
// 我们获得了最后一个孩子结点的编号,然后加1,便是新的编号
QString num = root.lastChild().toElement().attribute(tr("编号"));
int count = num.toInt() +1;
id.setValue(QString::number(count));
book.setAttributeNode(id);
text = doc.createTextNode(ui->lineEdit_title->text());
title.appendChild(text);
text = doc.createTextNode(ui->lineEdit_author->text());
author.appendChild(text);
book.appendChild(title);
book.appendChild(author);
root.appendChild(book);
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return ;
QTextStream out(&file);
doc.save(out,4); //将文档保存到文件,4为子元素缩进字符数
file.close();
ui->listWidget->clear(); //最后更改显示为“添加成功!”
ui->listWidget->addItem(tr("添加成功!"));
}
这里先用只读方式打开XML文件,将其读入doc中,然后关闭。我们将新的节点加入到最后面,并使其“编号”为以前的最后一个节点的编号加1。最后我们再用只写的方式打开XML文件,将修改完的doc写入其中。运行程序,效果如下图所示。
再次查看全部信息,可以看到新的节点已经添加了,如下图所示。
四、查找、删除、更新操作
因为这三个功能都要先利用“编号”进行查找,所以我们放在一起实现。
1.首先将界面上“图书编号”后面的Line Edit部件的objectName更改为lineEdit_id。
2.在mainwindow.h文件中添加public类型的函数声明:
void doXml(constQString operate);
我们使用这个函数来完成三种不同的操作,根据参数来判断不同的操作。
3.然后到mainwindow.cpp中添加该函数的定义:
void MainWindow::doXml(const QString operate)
{
ui->listWidget->clear();
ui->listWidget->addItem(tr("没有找到相关内容!"));
QFile file("my.xml");
if (!file.open(QIODevice::ReadOnly)) return ;
QDomDocument doc;
if (!doc.setContent(&file))
{
file.close();
return ;
}
file.close();
QDomNodeList list = doc.elementsByTagName(tr("图书"));
// 以标签名进行查找
for(int i=0; i<list.count(); i++)
{
QDomElement e = list.at(i).toElement();
// 如果元素的“编号”属性值与我们所查的相同
if(e.attribute(tr("编号")) == ui->lineEdit_id->text())
{
// 如果元素的“编号”属性值与我们所查的相同
if(operate == "delete") //如果是删除操作
{
QDomElement root = doc.documentElement(); //取出根节点
root.removeChild(list.at(i)); //从根节点上删除该节点
QFile file("my.xml"); //保存更改
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return ;
QTextStream out(&file);
doc.save(out,4);
file.close();
ui->listWidget->clear();
ui->listWidget->addItem(tr("删除成功!"));
}
else if(operate == "update") //如果是更新操作
{
QDomNodeList child = list.at(i).childNodes();
//找到它的所有子节点,就是“书名”和“作者”
child.at(0).toElement().firstChild().setNodeValue(ui->lineEdit_title->text());
//将它子节点的首个子节点(就是文本节点)的内容更新
child.at(1).toElement().firstChild().setNodeValue(ui->lineEdit_author->text());
QFile file("my.xml"); //保存更改
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return ;
QTextStream out(&file);
doc.save(out,4); //保存文档,4为子元素缩进字符数
file.close();
ui->listWidget->clear();
ui->listWidget->addItem(tr("更新成功!"));
}
else if(operate == "find") //如果是查找操作
{
ui->listWidget->clear();
ui->listWidget->addItem(e.tagName()+e.attribute(tr("编号")));
QDomNodeList list = e.childNodes();
for(int i=0; i<list.count(); i++)
{
QDomNode node = list.at(i);
if(node.isElement())
ui->listWidget->addItem(" "+node.toElement().tagName()
+" : "+node.toElement().text());
}
}
}
}
}
4. 下面我们分别进入“查找”,“删除”,“更新”三个按钮的单击信号槽,更改如下:
// 查找 // 删除 // 更新void
下面运行程序,查找操作结果如下图所示。
然后对编号为1的图书进行更新,效果如下图所示。
更新后我们再次查看所有内容。如下图所示。
然后进行删除操作,如下图所示。
删除后再次查询所有内容。效果如下图所示。
结语
通过本节的例子可以看到使用DOM可以很方便的进行XML文档的随机访问,这也是它最大的优点。关于更多更详细的内容可以参考《Qt Creator快速入门》的相关章节。
涉及到的源码: myDom_2.zip (4.21 KB, 下载次数: 12) |
[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档相关推荐
- 【Qt】DOM创建和操作XML文档
00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 创建XML文档 04. 读取XML文档 05. 增加XML节点 06. 查找.删除.更新XML文档 07. 附录 01. ...
- 〖Python自动化办公篇⑧〗- word文件自动化 - 创建并生成 word 文档
万叶集
- 一篇就够,python 操作 word 文档,使用 python-docx 落地实现,写入篇
本篇博客为大家带来 Python 操作 docx 文档相关知识点. 主要涉及的内容为 python-docx ,一款可以操作 Word 文档(仅支持 docx)的第三方库. 文章目录 写在前面 创建一 ...
- [Qt教程] 第27篇 XML(一)使用DOM读取XML文档
[Qt教程] 第27篇 XML(一)使用DOM读取XML文档 楼主 发表于 2013-5-21 21:14:28 | 查看: 1001| 回复: 14 使用DOM读取XML文档 版权声明 该文章原创 ...
- [Qt教程] 第29篇 XML(三)Qt中的SAX
[Qt教程] 第29篇 XML(三)Qt中的SAX 楼主 发表于 2013-5-21 22:27:59 | 查看: 615| 回复: 5 Qt中的SAX 版权声明 该文章原创于Qter开源社区(ww ...
- [Qt教程] 第30篇 XML(四)使用流读写XML
[Qt教程] 第30篇 XML(四)使用流读写XML 楼主 发表于 2013-5-22 13:03:33 | 查看: 611| 回复: 0 使用流读写XML 版权声明 该文章原创于作者yafeili ...
- [Qt教程] 第22篇 数据库(二)编译MySQL数据库驱动
[Qt教程] 第22篇 数据库(二)编译MySQL数据库驱动 楼主 发表于 2013-5-13 21:28:02 | 查看: 1616| 回复: 12 编译MyQSL数据库驱动 版权声明 该文章原创 ...
- [Qt教程] 第32篇 网络(二)HTTP
[Qt教程] 第32篇 网络(二)HTTP 楼主 发表于 2013-8-28 17:21:28 | 查看: 637| 回复: 8 HTTP 版权声明 该文章原创于作者yafeilinux,转载请注明 ...
- [Qt教程] 第38篇 网络(八)TCP(二)
[Qt教程] 第38篇 网络(八)TCP(二) 楼主 发表于 2013-9-6 15:50:35 | 查看: 421| 回复: 3 TCP(二) 版权声明 该文章原创于作者yafeilinux,转载 ...
最新文章
- 输出值(1)初始化输出值
- [转载]在Eclipse CDT中编译含有多个main函数的项目
- BZOJ4589: Hard Nim(FWT 快速幂)
- Mock和Java单元测试中的Mock框架Mockito介绍
- Eigen入门之密集矩阵 8 - resharp slicing切片
- h5首页加载慢_H5网站制作注意了
- 软件数控编程_这么多CNC数控编程软件, 你觉得哪个好?
- delphi中Record 和Packed Record的区别
- 编程开发之--单例模式(2)
- mysql忘记root密码安装_MySql忘记root密码的解决方法
- 机器学习笔记(一):机器的学习定义、导数和最小二乘 | 凌云时刻
- PSPNet | 语义分割及场景分析
- WYSE S10、WYSE V90、HP T5740瘦客机评测
- 指纹识别综述(11): 专利
- qnap raid5升级raid6_实践出真知!100TB的RAID5到底能否重建成功?
- win10家庭版解决“管理员已阻止你运行此应用”
- 必须得会的汽车ECU研发基础--ECU软件架构概览3
- Doris进阶——初识Doris_FE、BE、BROKER的扩缩容
- 轻量级工作流引擎snaker 2.0.0
- 站长必备WordPressCMS采集插件实现稳定收录
热门文章
- Crystal Reports basic for Visual Studio 2008部署
- 计算机位数与内存相关,弄懂电脑的各种位数、内存、存储
- linux 信号量锁 内核,Linux内核中锁机制之信号量、读写信号量
- python的基本语术_Python中的基本语句详细资料说明
- mysql5.7命中率_MySQL5.7中 performance和sys schema中的监控参数解释(推荐)
- 【2012百度之星/初赛上】B:小小度刷礼品
- The Common Language Runtime (CLR)
- Homework 8 测试计划
- # EXP8 Web基础
- 三、python+selenium