咔片PPT · AI自动生成演示文稿,模板丰富、排版精美 讯飞智文 · 一键生成PPT和Word,高效应对学习与办公

导语

在上一节中我们用手写的方法建立了一个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 ,然后在构造函数中添加如下代码:

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 ,然后在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; ilistWidget->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; ilineEdit_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; ilistWidget->addItem(" "+node.toElement().tagName() +" : "+node.toElement().text()); } } } } }

4.下面我们分别进入“查找”,“删除”,“更新”三个按钮的单击信号槽,更改如下:

// 查找 void MainWindow::on_pushButton_clicked() { doXml("find"); } // 删除 void MainWindow::on_pushButton_2_clicked() { doXml("delete"); } // 更新void MainWindow::on_pushButton_3_clicked() { doXml("update"); }

下面运行程序,查找操作结果如下图所示。

然后对编号为1的图书进行更新,效果如下图所示。

更新后我们再次查看所有内容。如下图所示。

然后进行删除操作,如下图所示。

删除后再次查询所有内容。效果如下图所示。

结语

通过本节的例子可以看到使用DOM可以很方便的进行XML文档的随机访问,这也是它最大的优点。关于更多更详细的内容可以参考《Qt Creator快速入门》的相关章节。