Qt 史上最详细 - “操作XML文件” - 笔记

Posted cpp_learner

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 史上最详细 - “操作XML文件” - 笔记相关的知识,希望对你有一定的参考价值。

XML文件可以用来存储项目中的数据,它相当于一个简单的数据库。

XML文件在实际开发中可以经常使用的,因为它非常方便的存储数据,方便存储、方便读取、方便查看、方便管理等。

下面将使用QT语言编写代码操作XML文件 - 增删改查。



一、准备工作

首先看一下XML文件的组成部分
在这里插入图片描述
描述信息:这个是xml文件必须要有的一段描述语句;
根节点:xml文件由只有一个根节点(仅有),它是所有子节点的父节点;
子节点:可有多个,必须在根节点内;
属性:存储数据的一种方式。

Qt中提供了QtXml模块来进行xml文件的处理,其中它有3中方式进行操作xml文件;这里主要讲解DOM方式。

操作xml文件需要添加头文件:
#include < QtXml >
#include < QDomDocument >

并且在创建项目时:

  1. Visual Studio 编译环境需要勾选xml模块,如下图
    勾选xml模块
  2. QT编译环境需要向.pro文件里面添加QT+=xml

二、创建

创建XML文件,并写入内容

1. 创建一个xml文件

// 打开或者创建一个XML文件
QFile file("QT_XML.xml");
// 文件存在则创建,否则创建一个文件
if (!file.open(QFileDevice::ReadWrite | QFileDevice::Truncate)) {
	QMessageBox::information(NULL, "提示", "文件打开或创建失败!");
	return;
}

2. 创建一个XML类

QDomDocument doc;

3. 创建XML头部格式

// 创建XML处理类,通常用于处理第一行描述信息
QDomProcessingInstruction instruction;

// 创建XML头部格式
instruction = doc.createProcessingInstruction("xml", "version=\\"1.0\\" encoding=\\"UTF-8\\"");

// 添加到XML文件中
doc.appendChild(instruction);

如下图,就是创建这么一行
在这里插入图片描述

4. 创建根节点

使用createElement方法进行创建,创建完成后使用appendChild方法添加到xml文档中

// 创建根节点
QDomElement root = doc.createElement("Library");
doc.appendChild(root);

如下图
在这里插入图片描述

5. 添加子节点

这里只是单纯的添加一个子节点,并没有其他元素

QDomElement book = doc.createElement("Book");
root.appendChild(book);

如下图
在这里插入图片描述

6. 添加带属性的子节点

使用setAttribute可以简单的给节点添加属性值;使用createElement是创建一个节点元素;

QDomElement book1 = doc.createElement("Book1");

// 给节点创建属性
book1.setAttribute("ID", 1);
book1.setAttribute("Name", "水浒传");	// 参数一是字符串,参数二可以是任何类型
book1.setAttribute("Price", 64.5);

// 创建子元素
QDomElement description = doc.createElement("Description");
	
// 设置尖括号中的值
QDomText text = doc.createTextNode("108个拆迁户");

// 添加关系
description.appendChild(text);
book1.appendChild(description);

// 添加子元素2
QDomElement Page = doc.createElement("Page");
QDomText text2 = doc.createTextNode("100页");
Page.appendChild(text2);
book1.appendChild(Page);

// 添加到根节点中
root.appendChild(book1);

流程:
首先创建一个节点,为该节点设置属性值,然后在创建两个子节点,并设置尖括号间的值,最后他们两被添加到第一个子节点中,然后第一个子节点被添加到根节点中,形成一种树结构。如下图
在这里插入图片描述

7. 将doc写入xml文件

需要使用到文件流QTextStream

QTextStream stream(&file);
doc.save(stream, 4);		// 缩进四格

file.close();

8. 创建xml文件并插入元素节点,总代码如下

// 创建XML文件,并写入内容
void createXML() {
	// 打开或者创建一个XML文件
	QFile file("QT_XML.xml");
	// 文件存在则创建,否则创建一个文件
	if (!file.open(QFileDevice::ReadWrite | QFileDevice::Truncate)) {
		QMessageBox::information(NULL, "提示", "文件打开或创建失败!");
		return;
	}

	// 创建一个XML类
	QDomDocument doc;

	// 创建XML处理类,通常用于处理第一行描述信息
	QDomProcessingInstruction instruction;

	// 创建XML头部格式
	instruction = doc.createProcessingInstruction("xml", "version=\\"1.0\\" encoding=\\"UTF-8\\"");

	// 添加到XML文件中
	doc.appendChild(instruction);

	// 创建根节点
	QDomElement root = doc.createElement("Library");
	doc.appendChild(root);

	/******************************************************************************************************************/

	// 添加子节点
	QDomElement book = doc.createElement("Book");
	root.appendChild(book);

	/*******************************************************************************************************************/

	// 添加带属性的子节点
	QDomElement book1 = doc.createElement("Book1");

	// 给节点创建属性
	book1.setAttribute("ID", 1);
	book1.setAttribute("Name", "水浒传");	// 参数一是字符串,参数二可以是任何类型
	book1.setAttribute("Price", 64.5);

	// 创建子元素
	QDomElement description = doc.createElement("Description");
	
	// 设置尖括号中的值
	QDomText text = doc.createTextNode("108个拆迁户");

	// 添加关系
	description.appendChild(text);
	book1.appendChild(description);

	// 添加子元素2
	QDomElement Page = doc.createElement("Page");
	QDomText text2 = doc.createTextNode("100页");
	Page.appendChild(text2);
	book1.appendChild(Page);

	// 添加到根节点中
	root.appendChild(book1);

	/*******************************************************************************************************************/

	// 添加子节点3
	QDomElement book3 = doc.createElement("Book1");
	book3.setAttribute("ID", 2);
	book3.setAttribute("Name", "三国演义");
	book3.setAttribute("Price", 66.5);
	QDomElement description2 = doc.createElement("Description");
	QDomText text3 = doc.createTextNode("魏蜀吴打架");
	description2.appendChild(text3);
	book3.appendChild(description2);
	QDomElement page = doc.createElement("Page");
	QDomText text4 = doc.createTextNode("300页");
	page.appendChild(text4);

	book3.appendChild(page);
	root.appendChild(book3);

	/*******************************************************************************************************************/

	// 将其写入到xml文件中
	QTextStream stream(&file);
	doc.save(stream, 4);		// 缩进四格

	file.close();
}

当执行完成后,会在项目路径创建一个xml文件,内容如下图:
在这里插入图片描述


三、添加

往xml文件中添加节点元素

例:
/* 创建一个一级子节点,子节点包含属性,包含二级子节点 */

1.打开文件,并定义xml文档类,并关联file文件

简单来说,对已经存在的xml文件,我们操作它前,需要先使用xml对象与文件对象进行关联

// 打开文件
QFile file("QT_XML.xml");
if (!file.open(QFileDevice::ReadOnly)) {
	QMessageBox::information(NULL, "提示", "文件打开失败!");
	return;
}

QDomDocument doc;

// 将doc与file关联起来
// 这个函数从IO设备dev中读取XML文档,如果内容被成功解析,则返回true;否则返回false。
if (!doc.setContent(&file)) {
	QMessageBox::information(NULL, "提示", "操作的文件不是XML文件!");
	file.close();
	return;
}
// 关联后可以关闭文件了
file.close();

2. 获取根节点

获取根节点对象

QDomElement root = doc.documentElement();

3. 创建一级子节点,并设置属性

使用createElement可以创建子节点元素;使用setAttribute可以设置属性

QDomElement book = doc.createElement("Book1");
book.setAttribute("ID", 3);		// 参数1是字符串,参数2可以是任何类型
book.setAttribute("Name", "西游记");
book.setAttribute("Price", "68.5");

假设创建好后,在xml文件中是这样显示的:
在这里插入图片描述

4. 为一级子节点创建子节点

QDomElement description = doc.createElement("Description");	// 创建节点
QDomText text = doc.createTextNode("两个人,一匹马,两个动物");	// 创建节点尖括号间的值
description.appendChild(text);	// 尖括号间的值的对象被添加到2级子节点中
book.appendChild(description);	// 2级子节点被添加到1级子节点中

QDomElement page = doc.createElement("Page");
text = doc.createTextNode("81页");
page.appendChild(text);
book.appendChild(page);

假设创建好后,在xml文件中是这样显示的:
在这里插入图片描述

5. 将一级子节点添加到根节点中

记得,当子节点们操作完成后,需要添加到根节点中,否则是无法添加成功的

// 添加到根节点
root.appendChild(book);

6. 使用文件流写入xml文件中

if (!file.open(QFileDevice::WriteOnly | QFileDevice::Truncate)) {
	QMessageBox::information(NULL, "提示", "文件打开失败!");
	return;
}

// 输出到文件
QTextStream stream(&file);
doc.save(stream, 4);	// 缩进4格
file.close();

7. 为已存在的xml文件添加节点元素,总代码如下

// 往XML文件中写内容(添加内容)
void addXML() {
	/* 创建一个一级子节点,子节点包含属性,包含二级子节点*/

	// 打开文件
	QFile file("QT_XML.xml");
	if (!file.open(QFileDevice::ReadOnly)) {
		QMessageBox::information(NULL, "提示", "文件打开失败!");
		return;
	}

	QDomDocument doc;

	// 将doc与file关联起来
	// 这个函数从IO设备dev中读取XML文档,如果内容被成功解析,则返回true;否则返回false。
	if (!doc.setContent(&file)) {
		QMessageBox::information(NULL, "提示", "操作的文件不是XML文件!");
		file.close();
		return;
	}
	file.close();

	// 获取根节点
	QDomElement root = doc.documentElement();

	// 创建一级节点
	QDomElement book = doc.createElement("Book1");
	book.setAttribute("ID", 3);
	book.setAttribute("Name", "西游记");
	book.setAttribute("Price", "68.5");

	// 创建二级节点1
	QDomElement description = doc.createElement("Description");
	QDomText text = doc.createTextNode("两个人,一匹马,两个动物");
	description.appendChild(text);
	book.appendChild(description);
	QDomElement page = doc.createElement("Page");
	text = doc.createTextNode("81页");
	page.appendChild(text);
	book.appendChild(page);

	 创建二级节点2,3,4
	//QDomElement author2 = doc.createElement("Author");
	//author2.setAttribute("Name", "吴承恩");
	//QDomElement author3 = doc.createElement("Author");
	//author3.setAttribute("Sex", "男");
	//QDomElement author4 = doc.createElement("Author");
	//author4.setAttribute("Age", 82);
	//book.appendChild(author2);
	//book.appendChild(author3);
	//book.appendChild(author4);

	// 添加到根节点
	root.appendChild(book);



	if (!file.open(QFileDevice::WriteOnly | QFileDevice::Truncate)) {
		QMessageBox::information(NULL, "提示", "文件打开失败!");
		return;
	}

	// 输出到文件
	QTextStream stream(&file);
	doc.save(stream, 4);	// 缩进4格
	file.close();
}

执行完如上代码,会在xml文件中添加指定的节点元素,如下图
在这里插入图片描述


四、删除

删除子节点

例:
/* 删除book 和 book1其中一个子节点 */

1. 与上类似,打开文件,关联文件,获取根节点

2. 删除Book节点

// 获取节点名字为Book的所有节点
QDomNodeList list = doc.elementsByTagName("Book");
for (int i = 0; i < list.size(); i++) {
	// 获取节点
	QDomElement element = list.at(i).toElement();	
	// 删除子节点
	root.removeChild(element);
}

流程:
首先通过elementsByTagName获取名字为“Book”的所有节点;遍历,获取其中每一个元素,转换为QDomElement 类型,进行删除

假设执行完,xml中将会是这样:
在这里插入图片描述

3. 删除指定的节点

上面是将节点名字为Book的节点都删除;那么,如果我只是向删除其中一个呢?
这里可以进行判断一下,在进行删除,使用属性的唯一值进行判断即可

list = doc.elementsByTagName("Book1");
int size = list.count();
for (int i = 0; i < list.count(); i++) {
	// 获取节点
	QDomElement element = list.at(i).toElement();

	// 进行判断(返回属性的值进行判断)
	if (element.attribute("ID") == "3") {
		root.removeChild(list.at(i));
	}
}

这里使用attribute方法获取对应参数的属性的值,然后与指定字符串进行判断,相等则使用removeChild方法进行删除
在这里插入图片描述

4. 最后再使用文件流输出到文件即可

与上面是相同的…

5. 删除节点,代码汇总

// 删除XML文件中的某些内容
void delXML() {
	/* 删除book 和 book1的一个子节点*/

	// 打开文件
	QFile file("QT_XML.xml");
	if (!file.open(QFileDevice::ReadOnly)) {
		QMessageBox::information(NULL, "提示", "文件打开失败!");
		return;
	}

	QDomDocument doc;
	if (!doc.setContent(&file)) {
		QMessageBox::information(NULL, "提示", "操作的文件不是XML文件!");
		file.close();
		return;
	}
	file.close();


	// 获得根节点
	QDomElement root = doc.documentElement();


	/* 删除所有的Book节点 */
	// 获取节点名字为Book的所有节点
	QDomNodeList list = doc.elementsByTagName("Book");
	for (int i = 0; i < list.size(); i++) {
		// 获取节点
		QDomElement element = list.at(i).toElement();	
		// 删除子节点
		root.removeChild(element);
	}

	// 获取节点名字为Book1的所有节点
	list = doc.elementsByTagName("Book1");
	int size = list.count();
	for (int i = 0; i < list.count(); i++) {以上是关于Qt 史上最详细 - “操作XML文件” - 笔记的主要内容,如果未能解决你的问题,请参考以下文章

史上最详细Ajax学习笔记

史上最详细的Maven使用笔记(建议收藏)

《数据结构与算法》---(哔哩哔哩--王卓老师笔记)史上最详细笔记

react-native学习笔记--史上最详细Windows版本搭建安装React Native环境配置

史上最详细的UE4安装教程(没有之一,就是史上最详细,不服气你来打我呀)

Python爬虫入门到实战-史上最详细的爬虫教程