1.数据格式
#ifndef XML_DATA_H
#define XML_DATA_H#include<QWidget>struct Student
{int s_id;QString s_name;double s_math_score;double s_english_score;};
struct Teacher{int t_id;QString t_name;QVector<Student> t_students_v;
};#endif // XML_DATA_H
2.xml示范
2.1 .h文件
#ifndef XML_EXAMPLE1_H
#define XML_EXAMPLE1_H#include <QObject>
#include"XML_Data.h"
#include <QtXml>
#include <QString>
#include <QDebug>
#include"tinyxml2.h"class Xml_Example1 : public QObject
{Q_OBJECT
public:explicit Xml_Example1(QObject *parent = nullptr);void saveXml_doc(const Student& stu,const QString& filePath);void saveXml_writer(const Student& stu,const QString& filePath);void saveXml_tinyxml2(const Student& stu,const QString& filePath);void saveXml_doc(const Teacher& tea,const QString& filePath);void saveXml_writer(const Teacher& tea,const QString& filePath);void saveXml_tinyxml2(const Teacher& tea,const QString& filePath);void loadXml_doc(Student& stu,const QString& filePath);void loadXml_tinyxml2(Student& stu,const QString& filePath);void loadXml_doc(Teacher& tea,const QString& filePath);void loadXml_tinyxml2(Teacher& tea,const QString& filePath);signals:
};#endif // XML_EXAMPLE1_H
2.2 .cpp文件
#include "xml_example1.h"Xml_Example1::Xml_Example1(QObject *parent): QObject{parent}
{}void Xml_Example1::saveXml_doc(const Student &stu, const QString &filePath)
{QDomDocument doc;// 创建根节点QDomElement root = doc.createElement("Student");doc.appendChild(root);// 创建子节点并设置属性QDomElement id = doc.createElement("ID");id.appendChild(doc.createTextNode(QString::number(stu.s_id)));root.appendChild(id);QDomElement name = doc.createElement("Name");name.appendChild(doc.createTextNode(stu.s_name));root.appendChild(name);QDomElement math_score = doc.createElement("MathScore");math_score.appendChild(doc.createTextNode(QString::number(stu.s_math_score)));root.appendChild(math_score);QDomElement english_score = doc.createElement("EnglishScore");english_score.appendChild(doc.createTextNode(QString::number(stu.s_english_score)));root.appendChild(english_score);// 保存到文件QFile file(filePath);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {qDebug() << "Failed to open file for writing.";return;}QTextStream out(&file);// out.setCodec("UTF-8");doc.save(out, 4);file.close();
}void Xml_Example1::saveXml_writer(const Student &stu, const QString &filePath)
{QFile file(filePath);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {qDebug() << "Failed to open file for writing.";return;}QXmlStreamWriter xmlWriter(&file);xmlWriter.setAutoFormatting(true); // 设置自动格式化,使XML文档更易读xmlWriter.writeStartDocument();xmlWriter.writeStartElement("Student");xmlWriter.writeTextElement("ID", QString::number(stu.s_id));xmlWriter.writeTextElement("Name", stu.s_name);xmlWriter.writeTextElement("MathScore", QString::number(stu.s_math_score));xmlWriter.writeTextElement("EnglishScore", QString::number(stu.s_english_score));xmlWriter.writeEndElement(); // 结束Student节点xmlWriter.writeEndDocument();file.close();
}void Xml_Example1::saveXml_tinyxml2(const Student &stu, const QString &filePath)
{// 创建一个 XML 文档对象tinyxml2::XMLDocument doc;// 创建根节点tinyxml2::XMLElement* root = doc.NewElement("Student");doc.InsertEndChild(root);// 添加学生信息作为子节点tinyxml2::XMLElement* idElement = doc.NewElement("ID");idElement->SetText(stu.s_id);root->InsertEndChild(idElement);tinyxml2::XMLElement* nameElement = doc.NewElement("Name");nameElement->SetText(stu.s_name.toStdString().c_str());root->InsertEndChild(nameElement);tinyxml2::XMLElement* mathScoreElement = doc.NewElement("MathScore");mathScoreElement->SetText(stu.s_math_score);root->InsertEndChild(mathScoreElement);tinyxml2::XMLElement* englishScoreElement = doc.NewElement("EnglishScore");englishScoreElement->SetText(stu.s_english_score);root->InsertEndChild(englishScoreElement);// 保存 XML 文档到文件doc.SaveFile(filePath.toStdString().c_str());}void Xml_Example1::saveXml_doc(const Teacher &tea, const QString &filePath)
{// 创建 QDomDocument 对象QDomDocument doc;// 创建根元素 <Teacher>QDomElement root = doc.createElement("Teacher");doc.appendChild(root);// 创建子元素 <ID> 和 <Name>,并添加到 <Teacher> 中QDomElement idElement = doc.createElement("ID");QDomText idText = doc.createTextNode(QString::number(tea.t_id));idElement.appendChild(idText);root.appendChild(idElement);QDomElement nameElement = doc.createElement("Name");QDomText nameText = doc.createTextNode(tea.t_name);nameElement.appendChild(nameText);root.appendChild(nameElement);// 创建子元素 <Student>,并添加到 <Teacher> 中for (const auto &stu : tea.t_students_v){QDomElement studentElement = doc.createElement("Student");QDomElement stuIdElement = doc.createElement("ID");QDomText stuIdText = doc.createTextNode(QString::number(stu.s_id));stuIdElement.appendChild(stuIdText);studentElement.appendChild(stuIdElement);QDomElement stuNameElement = doc.createElement("Name");QDomText stuNameText = doc.createTextNode(stu.s_name);stuNameElement.appendChild(stuNameText);studentElement.appendChild(stuNameElement);QDomElement mathScoreElement = doc.createElement("MathScore");QDomText mathScoreText = doc.createTextNode(QString::number(stu.s_math_score));mathScoreElement.appendChild(mathScoreText);studentElement.appendChild(mathScoreElement);QDomElement englishScoreElement = doc.createElement("EnglishScore");QDomText englishScoreText = doc.createTextNode(QString::number(stu.s_english_score));englishScoreElement.appendChild(englishScoreText);studentElement.appendChild(englishScoreElement);root.appendChild(studentElement);}// 将 QDomDocument 写入文件QFile file(filePath);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){qDebug() << "无法打开文件" << filePath;return;}QTextStream out(&file);// out.setCodec("UTF-8");doc.save(out, 4); // 缩进格式为4file.close();}void Xml_Example1::saveXml_writer(const Teacher &tea, const QString &filePath)
{// 创建文件对象QFile file(filePath);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){qDebug() << "无法打开文件" << filePath;return;}// 创建 XML 写入器QXmlStreamWriter xmlWriter(&file);xmlWriter.setAutoFormatting(true); // 设置自动格式化,便于阅读// 开始写入 XMLxmlWriter.writeStartDocument();xmlWriter.writeStartElement("Teacher");// 写入教师信息xmlWriter.writeTextElement("ID", QString::number(tea.t_id));xmlWriter.writeTextElement("Name", tea.t_name);// 写入学生信息for (const auto &stu : tea.t_students_v){xmlWriter.writeStartElement("Student");xmlWriter.writeTextElement("ID", QString::number(stu.s_id));xmlWriter.writeTextElement("Name", stu.s_name);xmlWriter.writeTextElement("MathScore", QString::number(stu.s_math_score));xmlWriter.writeTextElement("EnglishScore", QString::number(stu.s_english_score));xmlWriter.writeEndElement(); // 关闭<Student>节点}// 结束写入 XMLxmlWriter.writeEndElement(); // 关闭<Teacher>节点xmlWriter.writeEndDocument();// 关闭文件file.close();
}void Xml_Example1::saveXml_tinyxml2(const Teacher &tea, const QString &filePath)
{// 创建一个 XML 文档对象tinyxml2::XMLDocument doc;// 创建根节点tinyxml2::XMLElement *root = doc.NewElement("Teacher");doc.InsertEndChild(root);// 添加教师信息作为子节点tinyxml2::XMLElement *idElement = doc.NewElement("ID");idElement->SetText(tea.t_id);root->InsertEndChild(idElement);tinyxml2::XMLElement *nameElement = doc.NewElement("Name");nameElement->SetText(tea.t_name.toStdString().c_str());root->InsertEndChild(nameElement);// 添加学生信息作为子节点for (const auto &stu : tea.t_students_v){tinyxml2::XMLElement *studentElement = doc.NewElement("Student");root->InsertEndChild(studentElement);tinyxml2::XMLElement *idElement = doc.NewElement("ID");idElement->SetText(stu.s_id);studentElement->InsertEndChild(idElement);tinyxml2::XMLElement *nameElement = doc.NewElement("Name");nameElement->SetText(stu.s_name.toStdString().c_str());studentElement->InsertEndChild(nameElement);tinyxml2::XMLElement *mathScoreElement = doc.NewElement("MathScore");mathScoreElement->SetText(stu.s_math_score);studentElement->InsertEndChild(mathScoreElement);tinyxml2::XMLElement *englishScoreElement = doc.NewElement("EnglishScore");englishScoreElement->SetText(stu.s_english_score);studentElement->InsertEndChild(englishScoreElement);}// 保存 XML 文档到文件doc.SaveFile(filePath.toStdString().c_str());
}void Xml_Example1::loadXml_doc(Student &stu, const QString &filePath)
{QFile file(filePath);if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){// 文件无法打开qDebug()<<"文件无法打开";return;}QDomDocument xml_doc;if (!xml_doc.setContent(&file)){// XML 解析失败qDebug()<<"XML 解析失败";file.close();return;}QDomElement root = xml_doc.documentElement();stu.s_id = root.firstChildElement("ID").text().toInt();stu.s_name = root.firstChildElement("Name").text();stu.s_math_score = root.firstChildElement("MathScore").text().toDouble();stu.s_english_score = root.firstChildElement("EnglishScore").text().toDouble();file.close();
}void Xml_Example1::loadXml_tinyxml2(Student &stu, const QString &filePath)
{// 创建一个 XML 文档对象tinyxml2::XMLDocument doc;// 加载 XML 文件if(doc.LoadFile(filePath.toStdString().c_str()) != tinyxml2::XML_SUCCESS) {qDebug() << "Error loading XML file.";return;}// 获取根节点tinyxml2::XMLElement* root = doc.FirstChildElement("Student");if(!root) {qDebug() << "Root element 'Student' not found.";return;}// 解析子节点并填充到Student对象stu.s_id = root->FirstChildElement("ID")->IntText();const char* name = root->FirstChildElement("Name")->GetText();stu.s_name = QString(name);stu.s_math_score = root->FirstChildElement("MathScore")->IntText();stu.s_english_score = root->FirstChildElement("EnglishScore")->IntText();}void Xml_Example1::loadXml_doc(Teacher &tea, const QString &filePath)
{QFile file(filePath);if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){// 文件无法打开qDebug()<<"文件无法打开";return;}QDomDocument xml_doc;if (!xml_doc.setContent(&file)){// XML 解析失败qDebug()<<"XML 解析失败";file.close();return;}QDomElement root = xml_doc.documentElement();tea.t_id=root.firstChildElement("ID").text().toInt();tea.t_name=root.firstChildElement("Name").text();QDomNodeList studentList = root.elementsByTagName("Student");for(int i=0; i<studentList.count(); i++){QDomElement studentElement = studentList.at(i).toElement();Student student;student.s_id=(studentElement.firstChildElement("ID").text().toInt());student.s_name=(studentElement.firstChildElement("Name").text());student.s_math_score=(studentElement.firstChildElement("MathScore").text().toDouble());student.s_english_score=(studentElement.firstChildElement("EnglishScore").text().toDouble());// 将学生对象添加到教师对象中tea.t_students_v.append(student);}}void Xml_Example1::loadXml_tinyxml2(Teacher &tea, const QString &filePath)
{// 创建一个 XML 文档对象tinyxml2::XMLDocument doc;// 加载 XML 文件if(doc.LoadFile(filePath.toStdString().c_str()) != tinyxml2::XML_SUCCESS) {qDebug() << "Error loading XML file.";return;}// 获取根节点tinyxml2::XMLElement* root = doc.FirstChildElement("Teacher");if(!root) {qDebug() << "Root element 'Teacher' not found.";return;}// 解析子节点并填充到Teacher对象tea.t_id = root->FirstChildElement("ID")->IntText();tea.t_name = QString(root->FirstChildElement("Name")->GetText());// 读取每个学生的信息for(tinyxml2::XMLElement* student = root->FirstChildElement("Student"); student; student = student->NextSiblingElement("Student")) {Student s;// 解析学生的ID, Name, MathScore, 和 EnglishScorestudent->FirstChildElement("ID")->QueryIntText(&s.s_id);s.s_name = student->FirstChildElement("Name")->GetText();student->FirstChildElement("MathScore")->QueryDoubleText(&s.s_math_score);student->FirstChildElement("EnglishScore")->QueryDoubleText(&s.s_english_score);tea.t_students_v.append(s);// 将学生信息存储起来,这里的处理方式取决于具体的Teacher和Student的定义// 此处假设Teacher类和Student类已经定义,且有适当的方法来存储这些信息}// 获取学生节点// tinyxml2::XMLElement* studentElement = root->FirstChildElement("Students");// if(!studentElement) {// qDebug() << "Element 'Students' not found.";// return;// }// tinyxml2::XMLNode* studetsNode=root->// 解析学生节点// for(tinyxml2::XMLElement* studentNode = studentElement->FirstChildElement("Student");// studentNode;// studentNode = studentNode->NextSiblingElement("Student")) {// Student stu;// stu.s_id = studentNode->FirstChildElement("ID")->IntText();// stu.s_name = QString(studentNode->FirstChildElement("Name")->GetText());// stu.s_math_score = studentNode->FirstChildElement("MathScore")->DoubleText();// stu.s_english_score = studentNode->FirstChildElement("EnglishScore")->DoubleText();// // 将学生添加到老师的学生列表中// tea.t_students_v.push_back(stu);// }
}
3.测试
#include "widget.h"#include <QApplication>
#include"xml_example1.h"int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();Xml_Example1 x_e;Student stu;stu.s_id = 1;stu.s_name = "张三";stu.s_math_score = 90.5;stu.s_english_score = 85.3;Student stu2;stu2.s_id = 1;stu2.s_name = "张埃里克";stu2.s_math_score = 90.5;stu2.s_english_score = 85.3;Teacher t;t.t_id=11;t.t_name="tea";t.t_students_v.append(stu);t.t_students_v.append(stu2);x_e.saveXml_doc(stu, "student_doc.xml");x_e.saveXml_writer(stu, "student_writer.xml");x_e.saveXml_tinyxml2(stu, "student_tinyxml2.xml");x_e.saveXml_doc(t, "teacher_doc.xml");x_e.saveXml_writer(t, "teacher_writer.xml");x_e.saveXml_tinyxml2(t, "teacher_tinyxml2.xml");Student s3;// x_e.loadXml_doc(s3,"student_doc.xml");x_e.loadXml_tinyxml2(s3,"student_tinyxml2.xml");// qDebug()<<s3.s_name<<s3.s_english_score<<s3.s_math_score<<s3.s_id;Teacher t3;x_e.loadXml_doc(t3,"teacher_tinyxml2.xml");qDebug()<<t3.t_id<<t3.t_name<<t3.t_students_v.size();return a.exec();
}
4.效果图