今天介绍C++/Qt如何读写xml文件,xml文件一般用于作为配置文件使用。
C++
C++读写xml文件需要借助第三方来实现,比较好用的有tinyxml2和pugixml,对应的网址链接。
tinyxml2
pugixml
以tinyxml2为例,下载后进行解压可以看到以下文件:
项目代码中仅仅需要包含tinyxml2.h和tinyxml2.cpp两个文件即可,以读写这个xml为例
以下是读函数
void readXml()
{
tinyxml2::XMLDocument doc;
if (doc.LoadFile("1.xml") == XML_SUCCESS) {
XMLElement *data = doc.FirstChildElement("data");
if (data) {
XMLElement *profile = data->FirstChildElement("profile");
if (profile) {
cout<<profile->Attribute("id")<<","<<profile->Attribute("group")<<endl;
cout<<profile->FirstChildElement("name")->GetText()<<endl;
cout<<profile->FirstChildElement("dataID")->GetText()<<endl;
}
XMLElement *domain = data->FirstChildElement("domain");
if (domain) {
cout<<domain->FirstChildElement("name")->GetText()<<endl;
cout<<domain->FirstChildElement("domainID")->GetText()<<endl;
}
XMLElement *values = data->FirstChildElement("values");
if (values) {
XMLElement *valueNode = values->FirstChildElement("value");
while (valueNode != NULL) {
cout<<valueNode->Attribute("name")<<","<<valueNode->Attribute("type")<<","<<
valueNode->Attribute("defaultValue")<<","<<valueNode->GetText()<<endl;
valueNode = valueNode->NextSiblingElement();
}
}
}
}
}
执行之后可以看到打印
写函数
void writeXml()
{
tinyxml2::XMLDocument doc;
if (doc.LoadFile("1.xml") == XML_SUCCESS) {
XMLElement *data = doc.FirstChildElement("data");
if (data) {
XMLElement *profile = data->FirstChildElement("profile");
if (profile) {
profile->SetAttribute("id", "4321");
profile->SetAttribute("group", "group1");
profile->FirstChildElement("name")->SetText("user0000001");
profile->FirstChildElement("dataID")->SetText("QAZ123");
}
XMLElement *domain = data->FirstChildElement("domain");
if (domain) {
domain->FirstChildElement("name")->SetText("user0000002");
domain->FirstChildElement("domainID")->SetText("3");
}
XMLElement *values = data->FirstChildElement("values");
if (values) {
XMLElement *valueNode = values->FirstChildElement("value");
while (valueNode != NULL) {
valueNode->SetAttribute("name", "uuuu1");
valueNode->SetAttribute("type", "int32");
valueNode->SetAttribute("defaultValue", "666");
valueNode = valueNode->NextSiblingElement();
}
}
}
doc.SaveFile("1.xml");
}
}
执行后查看对应文件
可以看到文件已被修改。
Qt
Qt读写xml文件可以使用QDomDocument或者QXmlStreamReader(QXmlStreamWriter),其中前者是获取整个dom树操作,后者是按照读文件一样按行读取。以下以QDomDocument为例。
首先pro文件包含xml模块:
QT += xml
以及头文件包含:
#include <QDomDocument>
同样是读刚刚的xml文件,以下是读函数
void readXml()
{
QFile file("1.xml");
if (file.open(QIODevice::ReadOnly)) {
QDomDocument doc;
QString errString;
if (doc.setContent(&file, &errString)) {
QDomElement data = doc.documentElement();
QDomElement profile = data.firstChildElement("profile");
if (!profile.isNull()) {
qDebug()<<profile.attribute("id")<<","<<profile.attribute("group");
QDomElement name = profile.firstChildElement("name");
QDomElement dataID = profile.firstChildElement("dataID");
qDebug()<<name.text();
qDebug()<<dataID.text();
}
QDomElement domain = data.firstChildElement("domain");
if (!domain.isNull()) {
QDomElement name = domain.firstChildElement("name");
QDomElement domainID = domain.firstChildElement("domainID");
qDebug()<<name.text();
qDebug()<<domainID.text();
}
QDomNodeList values = data.firstChildElement("values").childNodes();
for (int i = 0; i < values.size(); ++i) {
QDomElement value = values.at(i).toElement();
qDebug()<<value.toElement().text();
}
qDebug()<<data.nodeName();
} else qDebug()<<errString;
file.close();
}
}
执行后打印
写函数
void writeXml()
{
QFile file("1.xml");
if (file.open(QIODevice::ReadOnly)) {
QDomDocument doc;
QString errString;
if (doc.setContent(&file, &errString)) {
file.close();
QDomElement data = doc.documentElement();
QDomElement profile = data.firstChildElement("profile");
if (!profile.isNull()) {
profile.setAttribute("id", "111111");
profile.setAttribute("group", "g1");
profile.firstChildElement("name").firstChild().setNodeValue("User000001");
profile.firstChildElement("dataID").firstChild().setNodeValue("XYZ123");
}
QDomNodeList values = data.firstChildElement("values").childNodes();
for (int i = 0; i < values.size(); ++i) {
QDomElement value = values.at(i).toElement();
value.firstChild().setNodeValue("xxxx");
}
qDebug()<<data.nodeName();
file.open(QIODevice::WriteOnly|QIODevice::Truncate);
QTextStream stream(&file);
qDebug()<<doc.toString();
doc.save(stream, 1);
} else qDebug()<<errString;
}
}
注意修改节点值setNodeValue不是直接调用而是.firstChild().setNodeValue。执行后可以查看文件已经被修改