首页 > 代码库 > QT xml 读写

QT xml 读写

    最近用QT在做一个项目,需要存储设备信息。

deviceInfo.h文件:

#include <QWidget>#include <QtCore>
#include <QString>
#include <QFile>
#include <QVector>
#include <QtXml/QDomDocument>
#include <QtXml/QDomNodeList>
#include <QtXml/QDomElement>
#include <QtXml/QDomAttr>

class devicesInfo
{
//    Q_OBJECT
public:
    devicesInfo();
    ~devicesInfo();

private:
    QDomDocument doc;
    QString fileName;

//内部接口
private:
    void readXmlFile(); //读取xml文件

//外部接口
public:
    //获得ip地址的设备信息
    void getADeviceInfo(QString ip,QVector<QString> &deviceInfoVec);  
    //刷新设备信息到xml文件中
    void updateDeviceInfoXml(QString ip,QVector<QString> &deviceInfoVec);
};

deviceInfo.cpp文件:
devicesInfo::devicesInfo(){
    fileName = "devices.xml";
}

devicesInfo::~devicesInfo()
{

}

void devicesInfo::getADeviceInfo(QString ip, QVector<QString> &deviceInfoVec){
    //xml文件读到内存
    readXmlFile();
    //读取内存中的设备信息
    //获取根节点
    QDomElement root = doc.documentElement();

    QString tempInfo;
    QDomNode deviceNode = root.firstChild();
    for( ; !deviceNode.isNull(); deviceNode = deviceNode.nextSibling()){
        if(deviceNode.isElement()){
            QDomElement element = deviceNode.toElement();
            QDomNodeList deviceInfoList = element.childNodes();
            QString ipAdress = deviceInfoList.at(0).toElement().text();
            if(ipAdress != ip){
                //ip地址不匹配,则进入下次循环
                continue ;
            }
            //ip地址匹配,则把相应的设备信息放到vector中
            for(int i=1; i<deviceInfoList.count(); i++){
                QDomNode nodechild = deviceInfoList.at(i);
                if(nodechild.isElement()){
                    tempInfo = nodechild.toElement().tagName() + ":" + nodechild.toElement().text();
                    deviceInfoVec.push_back(tempInfo);
                }
            }//end of for(内循环)
            //获取信息后返回,没有必要继续寻找
            return ;
        }
    }//end of for(外循环)
}
void devicesInfo::updateDeviceInfoXml(QString ip, QVector<QString> &deviceInfoVec){
    //读取xml文件到内存
    readXmlFile();
    //更新内存中的设备信息
    //获取根节点
    QDomElement root = doc.documentElement();

    QStringList tempInfoList;
    QDomNode deviceNode = root.firstChild();
    //记录每个设备中的属性信息是否成功更新,如果没有更新成功,则需要增加一个设备属性,默认是没有更新
    bool updateAttrInfoBool;
    //xml中这次需要更新的每个设备属性对应一个bool值,这次用户更新的设备信息中仍有该属性则true,否则false
    QVector<bool> xmlDeviceInfoBoolVec;
    qDebug() << "in update function:" << endl;
    //顺利遍历,寻找相应的ip地址,更新其中的设备信息
    for( ; !deviceNode.isNull(); deviceNode = deviceNode.nextSibling()){
        if(deviceNode.isElement()){
            QDomElement deviceElement = deviceNode.toElement();
            QDomNodeList deviceInfoList = deviceElement.childNodes();
            QString ipAdress = deviceInfoList.at(0).toElement().text();
            if(ipAdress != ip){
                //ip地址不匹配,则跳出本循环,进入下次循环
                qDebug() << "xml 中的 ip:" << ipAdress << " out." << endl;
                continue ;
            }
            //ip地址匹配
            //xml中的该匹配设备每个属性设置一个对应的 bool 值,并且默认是false
            for(int i=0; i<deviceInfoList.size(); i++){
                bool tempBool = false;
                xmlDeviceInfoBoolVec.push_back(tempBool);
            }
            //则把deviceInfoVec中的设备信息更新到该节点中
            for(int i=0; i<deviceInfoVec.size(); i++){
                updateAttrInfoBool = false;
                //把vec中的设备信息以“:” 分开,前面为tagname,后面为信息,并且跳过其中的空格
//                qDebug() << "第" << i << "行设备信息:" << deviceInfoVec[i] << endl;
                tempInfoList = deviceInfoVec[i].split(":",QString::SkipEmptyParts);
//                qDebug() << "ui : tagName : " << tempInfoList[0] << "deviceInfo : " << tempInfoList[1] << endl;
                //在内存中的ip设备信息中寻找tagName和用户输入的相匹配的,然后判断后面的信息是否一致
                for(int j=1; j<deviceInfoList.size(); j++){
                    //第 0 个是 ip 地址,所以从 j=1 开始
//                    qDebug() << "  xml : tagName:" <<  deviceInfoList.at(j).toElement().tagName()
//                             << "  deviceInfo:" << deviceInfoList.at(j).toElement().text() << endl;
                    if(tempInfoList[0] == deviceInfoList.at(j).toElement().tagName()){
                        //主要为真,则说明,xml文件和用户输入中都还有这个属性,则这个属性应该在更新完继续存在,也肯定会更新
                        xmlDeviceInfoBoolVec[j] = true;
                        updateAttrInfoBool = true;
                        if(tempInfoList[1] != deviceInfoList.at(j).toElement().text()){
                            //如果不一致,则更新
                            deviceInfoList.at(j).toElement().firstChild().setNodeValue(tempInfoList[1]);
                            //跳出本次更新设备属性信息的循环
                            break;
                        }
                    }
                }
                if(updateAttrInfoBool == false){
                    //如果没有更新成功,则增加一个设备属性
                    QDomElement deviceAttrInfo = doc.createElement(tempInfoList[0]);
                    QDomText text = doc.createTextNode(tempInfoList[1]);
                    deviceAttrInfo.appendChild(text);
                    deviceElement.appendChild(deviceAttrInfo);
                }
            }
            //根据用户输入的设备更新信息,删除xml中有的但是更新后应该没有的
            for(int i=1; i<deviceInfoList.size(); i++){
                if(xmlDeviceInfoBoolVec[i] == false){
                    //如果为假,删除该设备属性
                    deviceElement.removeChild(deviceInfoList.at(i));
                }
            }
            //内存中的设备信息写到xml文件
            QFile file(fileName);
            if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
                qDebug() << "open for add error!";
            }
            QTextStream out(&file);
            doc.save(out,4);
            file.close();
            //返回
            return ;
        }
    }//end of for(外循环)
}

参考资料:http://www.cnblogs.com/cy568searchx/p/3628601.html


本文出自 “太阳真圆” 博客,请务必保留此出处http://xuedengfeng.blog.51cto.com/7132939/1870937

QT xml 读写