Qt QDomComment读写Xml文件(含示例源码)

目录

一、利用Qt读写Xml文件的方式

二、使用QDomDocument类读写Xml文档

三、使用QDomDocument类读写Xml文档另外一种写法

 四、总结


一、利用Qt读写Xml文件的方式

        QDomDocument类:Qt的QDom模块提供了一个基于DOM的API,使用QDomDocument类可以方便地读取和操作XML文件。该类提供了DOM树结构的操作方法,可以实现XML的解析和生成等功能。优点是易于使用和修改XML文档,缺点是相对较慢,尤其是处理大型XML文档时。

        QXmlStreamReader和QXmlStreamWriter类:Qt的QXml模块提供了一种基于流的解析方法,使用QXmlStreamReader类可以有效地解析XML文件,而使用QXmlStreamWriter类可以方便地生成XML文件。这种方式具有较低的内存消耗和较快的解析速度,适用于处理大型XML文件。

        QXmlSimpleReader和QXmlDefaultHandler类:Qt还提供了一种基于事件的解析方式,使用QXmlSimpleReader类可以将XML文件解析为一系列的事件,然后使用QXmlDefaultHandler类重写事件处理方法,实现自定义的XML解析逻辑。这种方式具有较低的内存消耗和较快的解析速度,适用于处理大型XML文件,但需要编写相对复杂的处理逻辑

二、使用QDomDocument类读写Xml文档

17592a97e2ff4d7bb51fd0b46169d06d.png

写XML文档:

#include<iostream>
#include <QDomComment>
#include <QFile>
#include <QTextStream>
using namespace  std;
int main()
{

    //1、新建文件
    QFile file("/home/dwq/Desktop/xxx.xml");
    if(!file.open(QIODevice::WriteOnly))
    {
        return -1;
    }
    //2、新建DoM树
    QDomDocument doc;
    //3、添加说明信息
    QString insData=QString("version=\"1.0\" encoding=\"gb23121\"");
    QDomProcessingInstruction  ins=doc.createProcessingInstruction("xml",insData); //将文档声明添加到DOM树
    doc.appendChild(ins);
    //4、添加节点信息
    //4.1、添加根结点class
    QDomElement root=doc.createElement("class");
    doc.appendChild(root);
    //4.2、添加第一个Student结点
    QDomElement student1=doc.createElement("student"); //为student结点添加sex、age属性
    QDomAttr attr1=doc.createAttribute("sex");
    attr1.setNodeValue("男");
    student1.setAttributeNode(attr1);

    attr1 = doc.createAttribute("age");
    attr1.setNodeValue("18");
    student1.setAttributeNode(attr1);
    //为Student结点添加子节点id name
    QDomElement kidEle = doc.createElement("id");
    kidEle.appendChild(doc.createTextNode("01"));
    student1.appendChild(kidEle);

    kidEle = doc.createElement("name");
    kidEle.appendChild(doc.createTextNode("张三"));
    student1.appendChild(kidEle);
    root.appendChild(student1);


    /*当一个oDomElement添加到另一个QDomElement时,实际上是在创建原始元素的副本,并将该副本作为子节点
     *添加到目标元素中。这意味着添加操作操作会复制原始元素其相关数据,而不是移动原始元素。
     *基于上述原因代码QDomElementstudent2=dod.createElement("student");
     *可修改为student1=doc.createElement("student");
     *以student1之名继续以下的操作。QDomAttr亦是如此。
     *本例为使得逻辑更清晰,顾不做修改,综合实例会使用修改后的写法。
      **/
    //4.2、添加第二个student结点
    QDomElement student2=doc.createElement("student");
    //为Student结点添加sex、age属性

    QDomAttr attr2=doc.createAttribute("sex");
    attr2.setNodeValue("女");
    student2.setAttributeNode(attr2);

    attr2=doc.createAttribute("age");
    attr2.setNodeValue("18");
    student2.setAttributeNode(attr2);
    //为Student结点添加子节点id name
    kidEle =doc.createElement("id");
    kidEle.appendChild(doc.createTextNode("02"));
    student2.appendChild(kidEle);

    kidEle=doc.createElement("name");
    kidEle.appendChild(doc.createTextNode("李四"));
    student2.appendChild(kidEle);

    root.appendChild(student2);
    //3、保存
    QTextStream stream(&file);
    //将DOM文档保存到文档流中,并设置缩进字符为4
    doc.save(stream,4);

    //4、关闭文件
    file.close();
    doc.clear();


    return 0;
}

读Xml文档:

#include <iostream>
#include <QDomComment>
#include <QFile>
#include <QTextStream>
#include<QDebug>

using namespace std;

int main()
{
    //1、创建QFile对象,指定要打开的XML文件

    QFile file("/home/dwq/Desktop/xxx.xml");

    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"File open faild!";
        return-1;
    }

    //2、创建QDomDocument对象,用于解析XML
    QDomDocument doc;
    //通过QFile对象设置QDomDocument的内容
    if(!doc.setContent(&file))
    {
        file.close();
        return -1;
    }
    //关闭文件
    file.close();

    //3、解析XML
    //获取XML根结点

    QDomElement root= doc.documentElement();//class结点
    //遍历每个student结点
    QDomNodeList studentList=root.elementsByTagName("student");//通过标签名获取结点列表


    int listSize =studentList.size();
    for(int i = 0; i < listSize; ++i)
    {
        QDomElement student = studentList.at(i).toElement();    //通过索引获取QDomElement对象
        QString sex=student.attribute("sex");                   //获取sex属性值
        QString age =student.attribute("age");                  //获取age属性值
       
         /*
         *函数原型为
         *QDomElement firstChildElement(const QString &tagName = QString()) const;
         *解析:参数tagName是可选的,表示要查询的子元素结点的标签名。如果指定了tagName,则返回
         *第一个匹配标签的子元素结点;如果没有指定tagName,则返回第一个子元素结点。
         **/

        QString studentID=student.firstChildElement("id").text();       //获取id元素节点的文本内容
        QString studentName=student.firstChildElement("name").text();   //获取name元素节点的文本内容

        qDebug()<<"student:";
        qDebug()<<"sex:"<<sex;
        qDebug()<<"age:"<<age;
        qDebug()<<"studentID:"<<studentID;
        qDebug()<<"studentName:"<<studentName;


    }

    return 0;


}

三、使用QDomDocument类读写Xml文档另外一种写法

        有些时候我们会遇到一些具有重复结构或嵌套结构等复杂一点的Xml结构,当文件不是很庞大时同样也可以使用QDomDocument类读写Xml文件。这时我们需要一种较为条理的代码结构来完成这个任务。

Operation.h:

#ifndef OPERATION_H
#define OPERATION_H

#include <QString>
#include <QDomDocument>
#include <QList>

struct studentStruct
{
    studentStruct(){}
    /**
     * @brief read
     * @param element
     */
    void read(QDomElement &element);
    /**
     * @brief write
     * @param doc
     * @param element
     */
    void write(QDomDocument &doc,QDomElement& element);

    QString m_sex;
    QString m_age;
    QString m_id;
    QString m_name;
};

struct classStruct
{
    classStruct(){}
    /**
     * @brief read
     * @param element
     */
    void read(QDomElement& element);
    /**
     * @brief write
     * @param doc
     * @param element
     */
    void write(QDomDocument& doc,QDomElement& element);

    QList<studentStruct>    m_StuList;

};


class Operation
{
public:
    Operation();
    /**
     * @brief Init
     */
    void Init();
    /**
     * @brief Write
     * @param fileName
     */
    void Write(QString fileName);
    /**
     * @brief Read
     * @param fileName
     * @param classData
     */
    void Read(QString fileName,classStruct &classData);

private:

    classStruct m_class;
};

#endif // OPERATION_H

Operation.cpp:

#include "Operation.h"
#include <QTextStream>
#include <QDebug>

Operation::Operation()
{

}

void Operation::Init()
{
    studentStruct stu1,stu2;

    stu1.m_sex = "男";
    stu1.m_age = "18";
    stu1.m_id = "01";
    stu1.m_name = "张三";

    stu2.m_sex = "女";
    stu2.m_age = "18";
    stu2.m_id = "02";
    stu2.m_name = "李四";


    this->m_class.m_StuList.push_back(stu1);
    this->m_class.m_StuList.push_back(stu2);
}

void Operation::Write(QString fileName)
{
    //1、新建文件
    QFile file(fileName);
    file.open(QIODevice::WriteOnly);
    //2、新建DoM树
    QDomDocument doc;
    //3、添加说明信息
    QString insData=QString("version=\"1.0\" encoding=\"gb23121\"");
    QDomProcessingInstruction  ins=doc.createProcessingInstruction("xml",insData); //将文档声明添加到DOM树
    doc.appendChild(ins);
    //4、添加节点信息
    //添加根结点class
    QDomElement root=doc.createElement("class");
    doc.appendChild(root);

    this->m_class.write(doc,root);

    //5、保存
    QTextStream stream(&file);
    //将DOM文档保存到文档流中,并设置缩进字符为4
    doc.save(stream,4);

    //6、关闭文件
    file.close();
    doc.clear();
}

void Operation::Read(QString fileName, classStruct &classData)
{
    //1、创建QFile对象,指定要打开的XML文件

    QFile file2(fileName);

    if(!file2.open(QIODevice::ReadOnly))
    {
        qDebug()<<"file2 open faild!";
        return;
    }

    //2、创建QDomDocument对象,用于解析XML
    QDomDocument doc2;
    //通过QFile对象设置QDomDocument的内容
    if(!doc2.setContent(&file2))
    {
        file2.close();
        return;
    }
    //关闭文件
    file2.close();

    //3、解析XML
    //获取XML根结点

    QDomElement root2= doc2.documentElement();//class结点

    //将xml数据保存在结构中
    classData.read(root2);


}

void studentStruct::read(QDomElement &element)
{
    if(!element.isNull())
    {
        m_sex = element.attribute("sex");                   //获取sex属性值
        m_age = element.attribute("age");                   //获取age属性值
        m_id = element.firstChildElement("id").text();      //获取id元素节点的文本内容
        m_name = element.firstChildElement("name").text();  //获取name元素节点的文本内容
    }


}

void studentStruct::write(QDomDocument &doc, QDomElement &element)
{
    element.setAttribute("sex",m_sex);
    element.setAttribute("age",m_age);

    QDomElement kid=doc.createElement("id");
    kid.appendChild(doc.createTextNode(m_id));
    element.appendChild(kid);

    kid = doc.createElement("name");
    kid.appendChild(doc.createTextNode(m_name));
    element.appendChild(kid);
}

void classStruct::read(QDomElement &element)
{
    if(!element.isNull())
    {

#if 0
        QDomNodeList studentList = element.elementsByTagName("student");
        int listSize = studentList.size();

        for(int i = 0; i < listSize; ++i)
        {
            QDomElement student = studentList.at(1).toElement();
            studentStruct item;
            item.read(student);
            this->m_StuList.push_back(item);
        }

#endif
        QDomNode firstNode = element.firstChild();
        while(!firstNode.isNull())
        {
            studentStruct  item;
            QDomElement ele = firstNode.toElement();

            if(ele.nodeName() == "student")
            {
                item.read(ele);

                this->m_StuList.push_back(item);
            }

            firstNode = firstNode.nextSibling();
        }


    }

}

void classStruct::write(QDomDocument &doc, QDomElement &element)
{
    for(auto stu:m_StuList)
    {
        QDomElement kidEle = doc.createElement("student");
        stu.write(doc,kidEle);
        element.appendChild(kidEle);
    }
}

main.cpp:

#include <iostream>
#include <QDomComment>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include "Operation.h"

using namespace std;


int main()
{

    QString fileName = QString("/home/dwq/Desktop/xxx.xml");

    Operation op;

    //初始化数据
    op.Init();

    //书写文件
    op.Write(fileName);

    //读取文件
    classStruct xmlData;

    op.Read(fileName,xmlData);


    for(auto it : xmlData.m_StuList)
    {
        qDebug()<<"student:";
        qDebug()<<"sex:"<<it.m_sex;
        qDebug()<<"age:"<<it.m_age;
        qDebug()<<"studentID:"<<it.m_id;
        qDebug()<<"studentName:"<<it.m_name;
    }

    return 0;

}



执行结果:

a67ef5a8b3b24f4a926cef84ca0cec45.png

 四、总结

        选择使用哪种方式主要取决于项目需求和性能要求。如果需要简单地读取和修改XML文档,可以使用QDomDocument类;如果需要处理大型XML文件或需要较低的内存消耗,可以选择QXmlStreamReader和QXmlStreamWriter类或QXmlSimpleReader和QXmlDefaultHandler类。

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值