在 Qt 中,处理 XML 数据通常使用 Qt 提供的 QDomDocument、QXmlStreamReader 和 QXmlStreamWriter 类。这些类可以帮助你读取、修改和写入 XML 数据。
1. 使用 QDomDocument 处理 XML
QDomDocument 提供了对 XML 文档的 DOM(Document Object Model)结构的访问方式。这是一种树形结构,适用于对 XML 进行修改。
1.1. 读取 XML 文件
cpp
#include <QDomDocument>
#include <QFile>
#include <QDebug>
void readXml() {
QFile file("example.xml"); // 打开 XML 文件
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open file!";
return;
}
QDomDocument doc;
if (!doc.setContent(&file)) { // 设置文档内容
qDebug() << "Failed to parse XML!";
file.close();
return;
}
file.close();
// 获取根元素
QDomElement root = doc.documentElement();
qDebug() << "Root Element:" << root.tagName();
// 遍历子元素
QDomNodeList nodes = root.elementsByTagName("item"); // 假设有多个 <item> 元素
for (int i = 0; i < nodes.count(); ++i) {
QDomElement element = nodes.at(i).toElement();
if (!element.isNull()) {
qDebug() << "Item name:" << element.attribute("name");
qDebug() << "Item value:" << element.text();
}
}
}
1.2. 创建或修改 XML 文件
cpp
#include <QDomDocument>
#include <QFile>
#include <QTextStream>
#include <QDebug>
void writeXml() {
QDomDocument doc;
// 创建根元素
QDomElement root = doc.createElement("root");
doc.appendChild(root);
// 创建一个子元素 <item>
QDomElement item = doc.createElement("item");
item.setAttribute("name", "item1"); // 设置属性
item.appendChild(doc.createTextNode("This is item 1")); // 设置内容
root.appendChild(item);
// 创建第二个子元素 <item>
item = doc.createElement("item");
item.setAttribute("name", "item2");
item.appendChild(doc.createTextNode("This is item 2"));
root.appendChild(item);
// 将 XML 写入文件
QFile file("output.xml");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to open file for writing!";
return;
}
QTextStream stream(&file);
doc.save(stream, 4); // 将文档保存到文件中,4 是缩进的空格数
file.close();
}
1.3. 修改 XML 文件
cpp
void modifyXml() {
QFile file("example.xml");
if (!file.open(QIODevice::ReadWrite)) {
qDebug() << "Failed to open file!";
return;
}
QDomDocument doc;
if (!doc.setContent(&file)) {
qDebug() << "Failed to parse XML!";
file.close();
return;
}
file.close();
// 获取根元素
QDomElement root = doc.documentElement();
// 修改第一个 <item> 元素的内容
QDomNodeList nodes = root.elementsByTagName("item");
if (!nodes.isEmpty()) {
QDomElement element = nodes.at(0).toElement();
element.firstChild().setNodeValue("Updated item content");
// 将修改后的内容保存回文件
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QTextStream stream(&file);
doc.save(stream, 4);
file.close();
}
}
}
2. 使用 QXmlStreamReader 解析 XML
QXmlStreamReader 是基于事件的流解析器,适合用于逐个读取和处理大型 XML 文件。它是基于流的,不会将整个文件加载到内存中,因此适用于处理大型文件。
2.1. 读取 XML 数据
cpp
#include <QXmlStreamReader>
#include <QFile>
#include <QDebug>
void readXmlStream() {
QFile file("example.xml");
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open file!";
return;
}
QXmlStreamReader xml(&file);
while (!xml.atEnd()) {
xml.readNext();
if (xml.isStartElement()) {
// 如果是开始元素,输出标签名
qDebug() << "Start Element:" << xml.name().toString();
// 获取属性
if (xml.name() == "item") {
QString name = xml.attributes().value("name").toString();
qDebug() << "Item name:" << name;
}
}
if (xml.isCharacters()) {
// 如果是字符数据,输出内容
QString text = xml.text().toString();
qDebug() << "Text Content:" << text;
}
}
if (xml.hasError()) {
qDebug() << "Error parsing XML:" << xml.errorString();
}
file.close();
}
3. 使用 QXmlStreamWriter 写入 XML
QXmlStreamWriter 也基于事件的流写入器,适用于逐个写入 XML 数据。
3.1. 写入 XML 数据
cpp
#include <QXmlStreamWriter>
#include <QFile>
#include <QDebug>
void writeXmlStream() {
QFile file("output.xml");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to open file for writing!";
return;
}
QXmlStreamWriter xml(&file);
xml.setAutoFormatting(true); // 设置自动格式化
xml.writeStartDocument(); // 写入文档开始
// 写入根元素
xml.writeStartElement("root");
// 写入子元素 <item>
xml.writeStartElement("item");
xml.writeAttribute("name", "item1");
xml.writeCharacters("This is item 1");
xml.writeEndElement(); // 结束 <item> 元素
xml.writeStartElement("item");
xml.writeAttribute("name", "item2");
xml.writeCharacters("This is item 2");
xml.writeEndElement(); // 结束 <item> 元素
// 结束根元素
xml.writeEndElement();
xml.writeEndDocument(); // 写入文档结束
file.close();
}
4. 总结
- QDomDocument 是面向文档的,可以方便地读取、修改和创建 XML 文档。它适用于处理小型文件,并允许你修改整个文档。
- QXmlStreamReader 和 QXmlStreamWriter 是基于流的,适用于逐步读取和写入 XML 数据,适合处理大型文件。
- QDomDocument 使用起来更加简单直观,而 QXmlStreamReader 和 QXmlStreamWriter 则提供了更高效的内存管理,尤其是在处理大型 XML 文件时。