Qt下读写XML格式文件(使用QDomDocument类)

简述

XML是一种标记语言,被设计用来结构化存储以及传输信息,是一种常用的文档数据结构。
就我个人而言,Qt下读写XML格式文件可以有三种方法:
一是使用纯C++的rapidxml开源库。优点是速度快,媲美strlen()的速度;缺点是处理中文比较麻烦,编码只有ANSI格式。
二是使用QXmlStreamReader类,适当结合QXmlQuery类。优点是灵活性强,节约内存;缺点是理解起来相对较难,还需要一点数据库语言的知识。
三是使用QDomDocument类。是Qt下读写xml文件传统而普遍的做法,缺点就是如果读写的文件很大,会消耗大量的内存空间。
QDomDocument类可以理解为一个QFile,这个类的对象代表了整个文件,通常也是一个xml文件的主节点。还需使用到的类有QDomNode(节点基类)、QDomElement(节点类)、QDomText(内容)、QDomAttr(属性)、QDomProcessingInstruction(文件头)。

代码之路

读写一个用户名文件"user.xml",文件内容如下:

<?xml version = "1.0" encoding = "UTF-8"?>
<ALL>
  <DATA>
      <Name>1</Name>
      <Password>12</Password>
      <Describe>123</Describe>
      <Flag>1</Flag>
  </DATA>
  <DATA>
      <Name>2</Name>
      <Password>22</Password>
      <Describe>234</Describe>
      <Flag>1</Flag>
  </DATA>
</ALL>

读取上述内容的xml文件到一个结构体中

//用户信息结构体
struct UserStruct
{
  QString username; 
  QString password;
  QString decribe;
  int flag;    //用户权限
  void clear()
  {
    username = "";
    password = "";
    describe = "";
    flag = 1;
  }
};

读xml格式函数代码如下:

void readUserxml()
{
  UserStruct tmpInfo;
  QFile file(filename);
  if (!file.open(QIODevice::ReadOnly|QIODevice::Text))
  {
  	return;
  }
  QDomDocument doc;  //xml格式文件
  if (!doc.setContent(&file))
  {
  	file.close();
  	return;
  }
  file.close();
  QDomElement root = doc.documentElement(); //节点 ALL
    if (!root.isNull())
    {
        QDomNode node_a = root.firstChild(); //节点DATA
        while (!node_a.isNull())
        {
            QDomElement node_all = node_a.toElement(); //QDomnode转成QDomElement
            if (!node_all.isNull())
            {
                tmpInfo.clear(); //清空
                QDomElement n_name = node_all.firstChildElement("Name"); //Name节点

                if (!n_name.isNull())
                {
                    tmpInfo.username = n_name.text();
                }
                QDomElement n_passwd = node_all.firstChildElement("Password"); //Password节点
                if (!n_passwd.isNull())
                {
                    tmpInfo.password = n_passwd.text();
                }
                QDomElement n_describe = node_all.firstChildElement("Describe"); //Describe节点
                if (!n_describe.isNull())
                {
                    tmpInfo.describe = n_describe.text();
                }
                QDomElement n_flag = node_all.firstChildElement("Flag"); //Flag节点
                if (!n_flag.isNull())
                {
                    tmpInfo.flag  = n_flag.text().toInt();
                }

             //   //加入vector
             //   UserInfo.push_back(tmpInfo);
            }
            node_a = node_a.nextSibling();       //读取下一个DATA节点
        }
    }
}

写XML格式文件

void writeUserxml()
{
    //写入xml
    QFile file(Filename);
    if (!file.open(QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate))
    {
        return;
    }
    QDomDocument doc;
    QDomProcessingInstruction instruction;
    instruction = doc.createProcessingInstruction("xml", "version = \"1.0\" encoding = \"UTF-8\"");
    doc.appendChild(instruction);         //写入文件头

    QDomElement root = doc.createElement("ALL");
    doc.appendChild(root);

//    UserStruct tmp;
//    tmp.username = "11";
//    tmp.password = "1234";
//    tmp.describe = "321";
//    tmp.flag = 1;
//    UserInfo.push_back(tmp);

    int sum = UserInfo.size();

//    struct UserStruct
//    {
//        QString username;
//        QString password;
//        QString describe;
//        int flag;
//    };

    for (int i = 0; i < sum; ++i)
    {
        QDomElement node_data = doc.createElement("DATA");
        QDomElement node_name = doc.createElement("Name");
        QDomElement node_passwd = doc.createElement("Password");
        QDomElement node_describe = doc.createElement("Describe");
        QDomElement node_flag = doc.createElement("Flag");

        node_name.appendChild(doc.createTextNode(UserInfo[i].username));
        node_passwd.appendChild(doc.createTextNode(UserInfo[i].password));
        node_describe.appendChild(doc.createTextNode(UserInfo[i].describe));
        node_flag.appendChild(doc.createTextNode(QString::number(UserInfo[i].flag)));

        node_data.appendChild(node_name);
        node_data.appendChild(node_passwd);
        node_data.appendChild(node_describe);
        node_data.appendChild(node_flag);

        root.appendChild(node_data);
    }
    QTextStream out(&file);
    doc.save(out, 4);     //写入文件中
    file.close();
}

例子中没有涉及到节点属性,下面补充一下节点属性的写入:

QDomAttr atr = doc.createAttribute("id");
atr.setValue(str_id);
node_date.setAttributeNode(atr);

总结

Qt下使用QDomdocument类书写xml代码量相对不少,但是思路还是很清晰的。

猜你喜欢

转载自blog.csdn.net/lusanshui/article/details/84309151