返回顶部

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
View Code

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 }
View Code

 

posted @ 2020-07-23 22:54  zhengcixi  阅读(325)  评论(0编辑  收藏