Qt 读写xml文件(QDomDocument)

一、简述

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

三、读写样式

<?xml version='1.0' encoding='utf-8'?>
<日销售清单>
    <日期 date="2020-05-29">
        <时间 time="21:27:41">
            <厂家>二汽神龙</厂家>
            <品牌>毕加索</品牌>
            <报价>39</报价>
            <数量>1</数量>
            <金额>50</金额>
        </时间>
        <时间 time="21:27:51">
            <厂家>二汽神龙</厂家>
            <品牌>毕加索</品牌>
            <报价>39</报价>
            <数量>1</数量>
            <金额>50</金额>
        </时间>
        <时间 time="21:27:57">
            <厂家>二汽神龙</厂家>
            <品牌>毕加索</品牌>
            <报价>39</报价>
            <数量>1</数量>
            <金额>50</金额>
        </时间>
    </日期>
</日销售清单>

头文件

#ifndef DOCXML_H
#define DOCXML_H

#include <QString>
#include <QStringList>
#include <QDomDocument>
#include <QDomElement>

class DocXml
{
public:
    DocXml();

    static void CreateXml(const QString &filePath);     //创建xml 空文件
    static void AppendXml(const QString &filePath,QStringList list);
    static void WriteXml(QDomDocument &doc,QDomElement &root,QStringList &list);

    static void ReadXml(const QString &filePath,QStringList &fList,
                        QStringList &bList, QStringList &pList,
                        QStringList &nList, QStringList &tList);
};
#endif // DOCXML_H

创建空的XML文件

#include "docxml.h"
#include <QFile>
#include <QDomDocument>      //文件
#include <QDomProcessingInstruction>    //格式头部
#include <QDomElement>  //元素
#include <QTextStream>
#include <QDebug>
#include <QDateTime>

#define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]"

DocXml::DocXml()
{

}
void DocXml::CreateXml(const QString &filePath)
{
    QFile file(filePath);
    if(true == file.exists())       //如果文件存在就不创建
    {
        cout << "文件已存在";
        return;
    }
    else {
       if(file.open(QIODevice::WriteOnly))
       {
            //创建Xml文档
           QDomDocument doc;
           //创建XML头部格式
           QDomProcessingInstruction ins = doc.createProcessingInstruction("xml","version = \'1.0\' encoding = \'utf-8\'");
           //追加元素
           doc.appendChild(ins);
           //根节点元素
           QDomElement root = doc.createElement("日销售清单");
           doc.appendChild(root);

           //保存
           QTextStream stream(&file);       //文本流关联文件
           doc.save(stream,4);      //4 代表缩进4个字符

           file.close();        //关闭文件

       }
       else
       {
            cout << "打开文件失败";
       }
    }
}

追加 XML 文件

void DocXml::AppendXml(const QString &filePath, QStringList list)
{
    QFile file(filePath);
    if(file.open(QIODevice::ReadOnly))
    {
        //file和xml文档对象关联
        QDomDocument doc;
        if(doc.setContent(&file))   //关联成功
        {
            file.close();     //关闭文件
            //获取根节点元素
            QDomElement root = doc.documentElement();

            //获取当前时间
            QDateTime date = QDateTime::currentDateTime();
            QString strDate = date.toString("yyyy-MM-dd");

            //判断根节点下面有没有子节点
            if(root.hasChildNodes())
            {
                //查找最后一个子节点
                QDomElement lastEmt = root.lastChildElement();
                if(lastEmt.attribute("date") == strDate)
                {
                    //写有效数据
                    WriteXml(doc,lastEmt,list);
                }
                else
                {
                    //创建子节点元素
                    QDomElement dateEmt = doc.createElement("日期");
                    //dateEmt.setAttribute("date",strDate);   //建议写法
                    //创建date属性
                    QDomAttr dateAttr = doc.createAttribute("date");
                    //设置属性的值
                    dateAttr.setNodeValue(strDate);
                    //节点和属性关联
                    dateEmt.setAttributeNode(dateAttr);
                    //把日期节点追加到根节点
                    root.appendChild(dateEmt);

                    //写有效数据
                    WriteXml(doc,dateEmt,list);
                }
            }
            else
            {
                //创建子节点元素
                QDomElement dateEmt = doc.createElement("日期");
                ------------------------------------------------
                dateEmt.setAttribute("date",strDate);   //建议写法
                ------------------------------------------------
                //创建date属性
                //QDomAttr dateAttr = doc.createAttribute("date");
                //设置属性的值
                //dateAttr.setNodeValue(strDate);
                //节点和属性关联
                //dateEmt.setAttributeNode(dateAttr);
                //把日期节点追加到根节点
                root.appendChild(dateEmt);

                //写有效数据
                WriteXml(doc,dateEmt,list);

            }
            //保存文件
            if(file.open(QIODevice::WriteOnly))
            {
                QTextStream stream(&file);
                doc.save(stream,4);
                file.close();
            }
        }
        else
        {
            cout << "关联失败";
        }
    }
    else {
        cout << "打开文件失败";
    }
}

向XML文件中写入

void DocXml::WriteXml(QDomDocument &doc, QDomElement &root, QStringList &list)
{
    //当前时间获取
    QDateTime time = QDateTime::currentDateTime();
    QString strTime = time.toString("hh:mm:ss");

    //创建节点元素
    QDomElement timeEmt = doc.createElement("时间");
    timeEmt.setAttribute("time",strTime);      //设置属性值
    //把时间节点追加到日期节点后面
    root.appendChild(timeEmt);

    QDomElement factory = doc.createElement("厂家");
    QDomElement brand = doc.createElement("品牌");
    QDomElement price = doc.createElement("报价");
    QDomElement num = doc.createElement("数量");
    QDomElement total = doc.createElement("金额");

    QDomText text = doc.createTextNode(list.at(0));
    factory.appendChild(text);

    text = doc.createTextNode(list.at(1));
    brand.appendChild(text);

    text = doc.createTextNode(list.at(2));
    price.appendChild(text);

    text = doc.createTextNode(list.at(3));
    num.appendChild(text);

    text = doc.createTextNode(list.at(4));
    total.appendChild(text);

    timeEmt.appendChild(factory);
    timeEmt.appendChild(brand);
    timeEmt.appendChild(price);
    timeEmt.appendChild(num);
    timeEmt.appendChild(total);
}

从XML文件中读取

void DocXml::ReadXml(const QString &filePath,QStringList &fList,
                    QStringList &bList, QStringList &pList,
                    QStringList &nList, QStringList &tList)
{
    QFile file(filePath);
    if(file.open(QIODevice::ReadOnly))
    {
        //file和xml文档对象关联
        QDomDocument doc;
        if(doc.setContent(&file))
        {
            file.close();

            QDateTime date = QDateTime::currentDateTime();
            QString strDate = date.toString("yyyy-MM-dd");
            //获取根节点
            QDomElement root = doc.documentElement();
            if(root.hasChildNodes())
            {
            	---------------------------------------------------------------------
                //推荐用法
                QDomElement element = root.firstChildElement("日期");     //日期节点
                //判断节点是否为空,获取属性值
                if(!element.isNull())
                {
                     QString  qstr = element.attribute("date");
                }
				---------------------------------------------------------------------
                //找最后一个元素
                QDomElement lastEmt = root.lastChildElement();
                if(lastEmt.attribute("date") == strDate)   //判断有没有当天日期
                {
                    //找出当前日期下所有时间子节点
                    QDomNodeList list = lastEmt.childNodes();
                    for(int i = 0;i < list.size(); ++i)
                    {
                        //list.at(0).toElement();
                        //转换为元素,找到时间节点下所有的子节点
                        QDomNodeList nodeList =  list.at(i).toElement().childNodes();
                        //厂家
                        QString factory = nodeList.at(0).toElement().text();
                        fList.append(factory);
                        //
                        QString brand = nodeList.at(0).toElement().text();
                        bList.append(brand);

                        QString price = nodeList.at(0).toElement().text();
                        pList.append(price);

                        QString num = nodeList.at(0).toElement().text();
                        nList.append(num);

                        QString total = nodeList.at(0).toElement().text();
                        tList.append(total);
                    }
                }
                else
                {
                    cout << "没有当天日期";
                    return ;
                }
            }
            else
            {
                cout << "没有子节点";
                return ;
            }
        }
        else
            cout << "file 和 xml 文档对象关联失败";
    }
    else {
        cout << "读取时打开文件失败";
    }
}
好的,这是一个关于 Qt 的问题。QDomDocumentQt 中用于读写 XML 文件的类。其主要功能是将 XML 文件解析成 DOM 树表示,从而可以方便地进行修改、查询和输出操作。 在 Qt 中使用 QDomDocument 读写 XML 文件的步骤如下: 1. 创建 QDomDocument 对象,并设置 XML 文件的版本、编码和根节点。 2. 通过 QDomDocument 对象的 createElement() 方法创建节点,并通过 appendChild() 方法将其添加到 DOM 树中。 3. 通过 QDomDocument 对象的 createTextNode() 方法创建文本节点,并通过 appendChild() 方法将其添加到 DOM 树中。 4. 通过 QDomDocument 对象的 toByteArray() 方法将 DOM 树输出到字节数组中,或通过 save() 方法将 DOM 树保存到 XML 文件中。 以下是一个简单的示例代码,演示了如何使用 QDomDocument 读写 XML 文件: ```cpp #include <QFile> #include <QDomDocument> int main() { // 创建 QDomDocument 对象 QDomDocument doc; // 设置 XML 文件的版本和编码 doc.appendChild(doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"")); // 创建根节点 QDomElement root = doc.createElement("root"); doc.appendChild(root); // 创建子节点 QDomElement child = doc.createElement("child"); root.appendChild(child); // 创建文本节点 QDomText text = doc.createTextNode("Hello, world!"); child.appendChild(text); // 将 DOM 树输出到字节数组中 QByteArray xml = doc.toByteArray(); // 将 DOM 树保存到 XML 文件中 QFile file("test.xml"); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&file); out << doc.toString(); file.close(); } return 0; } ``` 这段代码创建了一个名为 test.xmlXML 文件,其内容为: ```xml <?xml version="1.0" encoding="UTF-8"?> <root> <child>Hello, world!</child> </root> ``` 希望这个示例代码可以帮助你了解如何使用 QDomDocumentQt读写 XML 文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值