Qt-操作xml文件
1 简介
参考视频:https://www.bilibili.com/video/BV1XW411x7AB?p=12
xml简介:可扩展标记语言,标准通用标记语言的子集,简称XML。是一种用于标记电子文件使其具有结构性的标记语言。
XML 标签没有被预定义,需要自行定义标签。XML 的设计宗旨是传输数据,而不是显示数据。XML 是独立于软件和硬件的信息传输工具。
2 xml文件格式
头部:xml文件的声明,说明xml版本和编码格式;
标签:标签需要成对出现。从(且包括)开始标签直到(且包括)结束标签的部分叫做XML 元素。
属性组:提供有关元素的额外信息,必须加引号。
xml文档形成的是一种树型结构。
3 测试及说明
下面简单介绍使用Qt创建一个xml文件,并对其进行简单的写入、读取操作。
先给出实现的效果,通过代码创建一个如下格式的xml文件,并通过id来查找到相应的节点信息。
1 <?xml version='1.0' encoding='utf-8'?> 2 <root> 3 <id id="1"> 4 <name>xiaoming</name> 5 <gender>male</gender> 6 <age>19</age> 7 <subject>Chinese</subject> 8 <score>78</score> 9 </id> 10 <id id="2"> 11 <name>xiaohong</name> 12 <gender>famale</gender> 13 <age>18</age> 14 <subject>Math</subject> 15 <score>88</score> 16 </id> 17 </root>
代码中的注释已经很详细了,就不再说说明步骤了,直接给出代码。
widget.h文件代码:
1 #ifndef WIDGET_H 2 #define WIDGET_H 3 4 #include <QWidget> 5 #include <QDomDocument> 6 7 namespace Ui { 8 class Widget; 9 } 10 11 class Widget : public QWidget 12 { 13 Q_OBJECT 14 15 public: 16 explicit Widget(QWidget *parent = 0); 17 ~Widget(); 18 19 //创建xml空文件 20 void create_xml(QString file_path); 21 //追加xml文件 22 void append_xml(QString file_path, int id, QStringList list); 23 //写xml文件 24 void write_xml(QDomDocument &doc, QDomElement &root, int id, QStringList &list); 25 //读xml文件 26 void read_xml(QString file_path, int id, QStringList &list); 27 28 private: 29 Ui::Widget *ui; 30 }; 31 32 #endif // WIDGET_H
widget.c文件代码:
1 #include "widget.h" 2 #include "ui_widget.h" 3 #include <QDomComment> 4 #include <QFile> 5 #include <QDebug> 6 7 Widget::Widget(QWidget *parent) : 8 QWidget(parent), 9 ui(new Ui::Widget) 10 { 11 ui->setupUi(this); 12 13 QString file_path = "../demo.xml"; 14 15 create_xml(file_path); 16 17 QStringList list; 18 //姓名 性别 年龄 学课 分数 19 list << "xiaoming" << "male" << "19" << "Chinese" << "78"; 20 append_xml(file_path, 1, list); 21 list.clear(); 22 list << "xiaohong" << "famale" << "18" << "Math" << "88"; 23 append_xml(file_path, 2, list); 24 list.clear(); 25 read_xml(file_path, 2, list); 26 qDebug() << list; 27 } 28 29 Widget::~Widget() 30 { 31 delete ui; 32 } 33 34 /* 35 * 创建xml文件,空文件,仅包含头部信息和根元素节点 36 * 参数file_path:文件存放路径 37 */ 38 void Widget::create_xml(QString file_path) 39 { 40 QFile file(file_path); //关联文件名字 41 if (true == file.exists()) { //如果存在不创建 42 qDebug() << "文件已经存在"; 43 return; 44 } 45 //只写方式打开文件 46 bool isOK = file.open(QIODevice::WriteOnly); 47 if (false == isOK) { 48 qDebug() << "writeOnly error"; 49 return; 50 } 51 //创建xml文档对象 52 QDomDocument doc; 53 //创建xml头部格式:<?xml version='1.0' encoding='utf-8'?> 54 QDomProcessingInstruction ins; 55 ins = doc.createProcessingInstruction("xml", "version=\'1.0\' encoding=\'utf-8\'"); 56 //追加元素 57 doc.appendChild(ins); 58 //创建根节点元素 59 QDomElement root = doc.createElement("root"); 60 doc.appendChild(root); 61 //保存 62 QTextStream stream(&file); //文本流关联文件 63 doc.save(stream, 4); //4 缩进字符 64 65 //关闭文件 66 file.close(); 67 } 68 69 /* 70 * 向xml文件中追加元素 71 * 参数file_path:文件存放路径 72 * 参数id:<id>元素节点的属性 73 * 参数list:<id>节点元素的子节点元素值 74 */ 75 void Widget::append_xml(QString file_path, int id, QStringList list) 76 { 77 QFile file(file_path); //关联文件名字 78 //只读方式打开文件 79 bool isOK = file.open(QIODevice::ReadOnly); 80 if (false == isOK) { 81 qDebug() << "ReadOnly error"; 82 return; 83 } 84 //文件file和xml关联 85 QDomDocument doc; 86 isOK = doc.setContent(&file); 87 if (false == isOK) { 88 qDebug() << "setContent error"; 89 } 90 //关联成功后,可以关闭文件 91 file.close(); 92 //获取根节点元素 93 QDomElement root = doc.documentElement(); 94 //判断根节点下有没有子节点 95 if (root.hasChildNodes()) { //如果有子节点 96 //查找最后一个子节点 97 QDomElement last_elem = doc.lastChildElement(); 98 write_xml(doc, last_elem, id, list); 99 } else { //没有子节点 100 //写有效数据 101 write_xml(doc, root, id, list); 102 } 103 //保存文件 104 isOK = file.open(QIODevice::WriteOnly); 105 if (false == isOK) { 106 qDebug() << "writeOnly error"; 107 return; 108 } 109 QTextStream stream(&file); 110 doc.save(stream, 4); 111 file.close(); 112 } 113 114 /* 115 * 给<root>根节点元素添加子节点元素 116 * 参数doc:xml文件 117 * 参数root:<root>节点元素 118 * 参数id:<id>节点元素属性值 119 * 参数list:<id>节点元素的子节点元素值 120 */ 121 void Widget::write_xml(QDomDocument &doc, QDomElement &root, int id, QStringList &list) 122 { 123 //添加<id>节点元素 124 QDomElement elem_id = doc.createElement("id"); 125 QDomAttr attr_id = doc.createAttribute("id"); 126 QString attr_str = QString::number(id); 127 attr_id.setNodeValue(attr_str); 128 elem_id.setAttributeNode(attr_id); 129 root.appendChild(elem_id); 130 131 //创建<姓名><性别><年龄><学课><分数>节点元素 132 QDomText text; 133 QDomElement name_elem = doc.createElement("name"); 134 text = doc.createTextNode(list.at(0)); 135 name_elem.appendChild(text); 136 QDomElement gender_elem = doc.createElement("gender"); 137 text = doc.createTextNode(list.at(1)); 138 gender_elem.appendChild(text); 139 QDomElement age_elem = doc.createElement("age"); 140 text = doc.createTextNode(list.at(2)); 141 age_elem.appendChild(text); 142 QDomElement subject_elem = doc.createElement("subject"); 143 text = doc.createTextNode(list.at(3)); 144 subject_elem.appendChild(text); 145 QDomElement score_elem = doc.createElement("score"); 146 text = doc.createTextNode(list.at(4)); 147 score_elem.appendChild(text); 148 //追加到<id>节点后面 149 elem_id.appendChild(name_elem); 150 elem_id.appendChild(gender_elem); 151 elem_id.appendChild(age_elem); 152 elem_id.appendChild(subject_elem); 153 elem_id.appendChild(score_elem); 154 } 155 156 /* 157 * 通过id查找信息 158 * 参数file_path:xml文件路径 159 * 参数id:查找的id 160 * 参数list:存放查找到的信息 161 */ 162 void Widget::read_xml(QString file_path, int id, QStringList &list) 163 { 164 QFile file(file_path); //关联文件名字 165 //只读方式打开文件 166 bool isOK = file.open(QIODevice::ReadOnly); 167 if (false == isOK) { 168 qDebug() << "ReadOnly error"; 169 return; 170 } 171 //文件file和xml关联 172 QDomDocument doc; 173 isOK = doc.setContent(&file); 174 if (false == isOK) { 175 qDebug() << "setContent error"; 176 } 177 //关联成功后,可以关闭文件 178 file.close(); 179 //获取根节点 180 QDomElement root = doc.documentElement(); 181 if (root.hasChildNodes()) { //有没有子节点 182 QDomNodeList list_nodes = root.childNodes(); 183 int i; 184 for (i = 0; i < list_nodes.size(); i++) { 185 if (id != list_nodes.at(i).toElement().attribute("id").toInt()) { 186 continue; 187 } 188 //转换为元素,找到<id>节点下的所有子节点 189 QDomNodeList sublist = list_nodes.at(i).toElement().childNodes(); 190 //name 191 QString name = sublist.at(0).toElement().text(); 192 list.append(name); 193 //gender 194 QString gender = sublist.at(1).toElement().text(); 195 list.append(gender); 196 //age 197 QString age = sublist.at(2).toElement().text(); 198 list.append(age); 199 //subject 200 QString subject = sublist.at(3).toElement().text(); 201 list.append(subject); 202 //score 203 QString score = sublist.at(4).toElement().text(); 204 list.append(score); 205 break; 206 } 207 if (i == list_nodes.size()) { 208 qDebug() << QString("没有id=%1的学生信息").arg(id); 209 return; 210 } 211 } else { //没有子节点 212 qDebug() << "没有子节点"; 213 return; 214 } 215 }