VS+QT——读写XML文件(含中文字符):从建工程开始

如题,今天在实现VS+QT——读写XML文件(含中文字符)时遇到很多问题,现做个总结!

附代码:https://download.csdn.net/download/qq_28662831/11212076

一、建立能使用XML模块的工程:

  1. QT Creator 有.pro文件,能直接修改.pro文件(qt += xml)即可使用xml模块,但是VS+QT生成的工程并没有.pro文件,这里,我找到两种方法:
    1. 在建立工程时选择XML模块
    2. 创建默认工程,在工程属性里面配置头文件.h、库文件.lib。配置方式参考博客《https://blog.csdn.net/u011295947/article/details/51596447

二、代码问题:

  • VS默认字符集格式是unicode(多字节),而XML默认格式是UTF-8字符集格式。

    • 从XML文件读出来的时候,已经是UTF-8格式了,所以不需要转换就可以正常显示中文字符。

    • 但是,从内存(unicode)写入到XML文件时,需要设置字符集为UTF-8,否则会乱码。即,写入之前,设置写入格式,否则VS默认以unicode格式写入,就会乱码。

三、代码实现:

  1. 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();
    }
    
  2. 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);
    };

     

  3. 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();
    }
    

 

三、总结:

本文主要总结两个问题:

  1. VS中没有.pro文件,怎么添加XML模块的使用。

  2. XML中含有中文字符时,在写入XML文件时,如何避免中文乱码。

注意:本文代码有参考别人的博客,但是,解决问题的方法是自己写的。转载请说明出处。

 

                

全部评论

相关推荐

真是做吐了🤮
投递美团等公司10个岗位 >
点赞 评论 收藏
分享
醒工硬件:如果你想投硬件,可以考虑这么改: 1.个人荣誉没太有保留价值,除非一页凑不满 2.主修课程太多了,可以考虑删减一部分,或者分成硬件和嵌入式2个简历,侧重点不一样 3.个人技能放到学习经历下面,项目经历上面。学习一下AD画板,你有基础一两周也差不多学会了,面试官问你就说你会(总不能拉你实操吧),公司里一般用AD和Cadence比较多,AD好上手一些。增加常用仪器工具说明,例如示波器、信号发生器、电子负载、烙铁、风枪等 4.项目,项目可以多换换行,挤在一起不好阅读。可以说下红外那边用什么接口,蓝牙那边用什么接口,用了哪些关键技术点,多用术语。如果你投硬件,就增加项目1描述比重,降低项目2描述比重
点赞 评论 收藏
分享
learYuan:🐕看了都摇头
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务