VS+QT——读写XML文件(含中文字符):从建工程开始
如题,今天在实现VS+QT——读写XML文件(含中文字符)时遇到很多问题,现做个总结!
附代码:https://download.csdn.net/download/qq_28662831/11212076
一、建立能使用XML模块的工程:
- QT Creator 有.pro文件,能直接修改.pro文件(qt += xml)即可使用xml模块,但是VS+QT生成的工程并没有.pro文件,这里,我找到两种方法:
- 在建立工程时选择XML模块
- 创建默认工程,在工程属性里面配置头文件.h、库文件.lib。配置方式参考博客《https://blog.csdn.net/u011295947/article/details/51596447》
- 在建立工程时选择XML模块
二、代码问题:
-
VS默认字符集格式是unicode(多字节),而XML默认格式是UTF-8字符集格式。
-
-
从XML文件读出来的时候,已经是UTF-8格式了,所以不需要转换就可以正常显示中文字符。
-
但是,从内存(unicode)写入到XML文件时,需要设置字符集为UTF-8,否则会乱码。即,写入之前,设置写入格式,否则VS默认以unicode格式写入,就会乱码。
-
三、代码实现:
- main.cpp
#include <QtCore/QCoreApplication> #include "AppConfigXML.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); AppConfig test; //test.readXMLFile("C:/Users/ww/Desktop/AppConfig.xml"); //test.ChangeXMLElement("C:/Users/ww/Desktop/AppConfig.xml", "RecognizeElapse", "000000"); //test.readXMLFile("C:/Users/ww/Desktop/AppConfig.xml"); test.readXMLElement("C:/Users/ww/Desktop/AppConfig.xml", "Skin"); qDebug() << QString::fromLocal8Bit("完成"); return a.exec(); }
- AppConfigXML.h
#pragma once #include <QFile> #include <QtXml> #include <QDomDocument> #include <QString> class AppConfig { public: AppConfig(); ~AppConfig(); void readXMLFile(QString path); void readXMLElement(QString path, QString ElementName); void ChangeXMLElement(QString path, QString ElementName, QString ElementValue); };
- AppConfigXML.cpp
#include "AppConfigXML.h" #include <QDebug> int AppConfig::LastSelectedDevice = 0;//初始化 AppConfig::AppConfig() { } AppConfig::~AppConfig() { } void AppConfig::readXMLFile(QString path) { QDomDocument doc; QFile file(path);//打开或创建文件 if (!file.open(QIODevice::ReadOnly)) return; if (!doc.setContent(&file)) { file.close(); return; } file.close(); QDomElement rootElem = doc.documentElement();//返回根节点元素 QDomNode rootNode = rootElem.firstChild();//获得第一个子节点 while (!rootNode.isNull()) { QDomElement fileElem = rootNode.toElement(); //将QDomNode转换为QDomElement。如果节点不是元素,则返回的对象将为null。 // QDomNodeList list=e.childNodes();//返回所有直接子节点的列表,如需要可遍历列表 if (!fileElem.isNull()) { qDebug() << fileElem.nodeName()<<":"<< fileElem.text();//text()返回此元素中包含的文本。 //if (fileElem.nodeName() == ElementName)//匹配某一个元素 //qDebug()<< fileElem.text(); } rootNode = rootNode.nextSibling();//下一个兄弟节点 } return; } void AppConfig::readXMLElement(QString path, QString ElementName) { QDomDocument doc; QFile file(path);//打开或创建文件 if (!file.open(QIODevice::ReadOnly)) return; if (!doc.setContent(&file)) { file.close(); return; } file.close(); QDomElement rootElem = doc.documentElement();//返回根节点元素 QDomNode rootNode = rootElem.firstChild();//获得第一个子节点 while (!rootNode.isNull()) { QDomElement fileElem = rootNode.toElement(); //将QDomNode转换为QDomElement。如果节点不是元素,则返回的对象将为null。 // QDomNodeList list=e.childNodes();//返回所有直接子节点的列表,如需要可遍历列表 if (!fileElem.isNull()) { //qDebug() << fileElem.nodeName() << ":" << fileElem.text();//text()返回此元素中包含的文本。 if (fileElem.nodeName() == ElementName)//匹配某一个元素 qDebug() << fileElem.nodeName() << ":" << fileElem.text();//text()返回此元素中包含的文本。 } rootNode = rootNode.nextSibling();//下一个兄弟节点 } return; } void AppConfig::ChangeXMLElement(QString path, QString ElementName, QString ElementValue) { QString name; QDomDocument doc; QFile file(path); if (!file.open(QIODevice::ReadOnly)) { return; } if (!doc.setContent(&file)) { file.close(); return; } file.close(); QDomElement rootElem = doc.documentElement();//返回根节点元素 QDomNode rootNode = rootElem.firstChild();//获得第一个子节点 while (!rootNode.isNull()) { QDomElement fileElem = rootNode.toElement();//将QDomNode转换为QDomElement。如果节点不是元素,则返回的对象将为null。 if (!fileElem.isNull()) { name = fileElem.tagName(); if (name == ElementName) { QDomElement newNode = doc.createElement(ElementName); QDomText text = doc.createTextNode(ElementValue); newNode.appendChild(text); rootElem.replaceChild(newNode, rootNode); } } rootNode = rootNode.nextSibling(); } QString xml = doc.toString(); if (!file.open(QFile::WriteOnly | QFile::Truncate))//Truncate:打开文件后,之前的内容将会消失(默认Truncate是打开的) { return; } QTextStream out(&file); //out << QString::fromLocal8Bit(xml.toStdString().c_str()); out.setCodec("UTF-8");//这里,XML是UTF-8的格式。这很重要 out << xml; file.close(); }
三、总结:
本文主要总结两个问题:
-
VS中没有.pro文件,怎么添加XML模块的使用。
-
XML中含有中文字符时,在写入XML文件时,如何避免中文乱码。
注意:本文代码有参考别人的博客,但是,解决问题的方法是自己写的。转载请说明出处。