使用Qt5的QXmlStreamWriter和QXmlStreamReader实现xml文件的写入和读取

Qt中实现xml文件写入和读取操作的方法有多种,但是总体来说,还是接下来要介绍的方法更加的方便快捷。
需要说明的是:QXmlStreamReader和SAX的作用是一致的,前者是作为后者的替代品出现的,而DOM(文档对象模型)是W3C推荐的标准,它不同于前者一行一行地读取,而是一次性读取到内存中以树型结构的方式存储,方便操作和随机访问,灵活性高,但是代价是当文件较大时读取需要费些时间。
下面基于我在实际项目中的一个小需求,通过编写一个小demo来介绍该内容。
第1步:使用QXmlStreamWriter实现xml文件的写入操作

void writeXML() {
    QFile file("../generateConfigureInfoFile/bg_train01.xml");
    if(!file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate)) {
        qDebug() << "failed to open bg_train01.xml";
        return;
    }
    QXmlStreamAttributes attributes;
    QXmlStreamWriter writer;
    writer.setCodec("UTF-8");
    writer.setDevice(&file);
    writer.setAutoFormatting(true);
    writer.writeStartDocument(); //编写文档的第一行
    writer.writeStartElement("ConfigInfo");

    writer.writeComment("开始保存第1行的配置数据!");
    writer.writeStartElement("RootDir");
    attributes.append("itemText", "BG-HAO(2873/2873)");
    attributes.append("dirBaseName", "BG-HAO");
    attributes.append("withSubDir", "false");
    attributes.append("showSubDir", "false");
    writer.writeAttributes(attributes);
    writer.writeStartElement("SubDir");
    attributes.clear();
    attributes.append("itemText", "/");
    attributes.append("dirBaseName", "BG-HAO");
    attributes.append("withSubDir", "false");
    attributes.append("showSubDir", "false");
    writer.writeAttributes(attributes);
    writer.writeTextElement("ImageSum", "2873");
    writer.writeEmptyElement("DirInfo");
    attributes.clear();
    attributes.append("dirFullName", "/home/liuqiang/Documents/BG/train/BG-HAO");
    attributes.append("imageNumber", "2873");
    writer.writeAttributes(attributes);
    writer.writeTextElement("Weight", "1.0");
    writer.writeEmptyElement("Label");
    attributes.clear();
    attributes.append("name", "(0)hao");
    attributes.append("color", "#12ec76");
    attributes.append("number", "0");
    writer.writeAttributes(attributes);
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeComment("第1行的配置数据保存完毕!");

    writer.writeComment("开始保存第2行的配置数据!");
    writer.writeStartElement("RootDir");
    attributes.clear();
    attributes.append("itemText", "BG-CHA(4222/4222)");
    attributes.append("dirBaseName", "BG-CHA");
    attributes.append("withSubDir", "false");
    attributes.append("showSubDir", "false");
    writer.writeAttributes(attributes);
    writer.writeStartElement("SubDir");
    attributes.clear();
    attributes.append("itemText", "/");
    attributes.append("dirBaseName", "BG-CHA");
    attributes.append("withSubDir", "false");
    attributes.append("showSubDir", "false");
    writer.writeAttributes(attributes);
    writer.writeTextElement("ImageSum", "4222");
    writer.writeEmptyElement("DirInfo");
    attributes.clear();
    attributes.append("dirFullName", "/home/liuqiang/Documents/BG/train/BG-CHA");
    attributes.append("imageNumber", "4222");
    writer.writeAttributes(attributes);
    writer.writeTextElement("Weight", "1.0");
    writer.writeEmptyElement("Label");
    attributes.clear();
    attributes.append("name", "(1)cha");
    attributes.append("color", "#0cc8f3");
    attributes.append("number", "1");
    writer.writeAttributes(attributes);
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeComment("第2行的配置数据保存完毕!");

    writer.writeComment("开始保存第3行的配置数据!");
    writer.writeStartElement("RootDir");
    attributes.clear();
    attributes.append("itemText", "train(7095/7095)");
    attributes.append("dirBaseName", "train");
    attributes.append("withSubDir", "true");
    attributes.append("showSubDir", "false");
    writer.writeAttributes(attributes);
    writer.writeStartElement("SubDir");
    attributes.clear();
    attributes.append("itemText", "/");
    attributes.append("dirBaseName", "train");
    attributes.append("withSubDir", "true");
    attributes.append("showSubDir", "false");
    writer.writeAttributes(attributes);
    writer.writeTextElement("ImageSum", "7095");
    writer.writeEmptyElement("DirInfo");
    attributes.clear();
    attributes.append("dirFullName", "/home/liuqiang/Documents/BG/train/BG-HAO");
    attributes.append("imageNumber", "2873");
    writer.writeAttributes(attributes);
    writer.writeEmptyElement("DirInfo");
    attributes.clear();
    attributes.append("dirFullName", "/home/liuqiang/Documents/BG/train/BG-CHA");
    attributes.append("imageNumber", "4222");
    writer.writeAttributes(attributes);
    writer.writeTextElement("Weight", "1.0");
    writer.writeEmptyElement("Label");
    attributes.clear();
    attributes.append("name", "(0)hao");
    attributes.append("color", "#12ec76");
    attributes.append("number", "0");
    writer.writeAttributes(attributes);
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeComment("第3行的配置数据保存完毕!");

    writer.writeComment("开始保存第4行的配置数据!");
    writer.writeStartElement("RootDir");
    attributes.clear();
    attributes.append("itemText", "train(7095/7095)");
    attributes.append("dirBaseName", "train");
    attributes.append("withSubDir", "true");
    attributes.append("showSubDir", "true");
    writer.writeAttributes(attributes);
    writer.writeStartElement("SubDir");
    attributes.clear();
    attributes.append("itemText", "BG-HAO(2873/2873)");
    attributes.append("dirBaseName", "BG-HAO");
    attributes.append("withSubDir", "false");
    attributes.append("showSubDir", "false");
    writer.writeAttributes(attributes);
    writer.writeTextElement("ImageSum", "2873");
    writer.writeEmptyElement("DirInfo");
    attributes.clear();
    attributes.append("dirFullName", "/home/liuqiang/Documents/BG/train/BG-HAO");
    attributes.append("imageNumber", "2873");
    writer.writeAttributes(attributes);
    writer.writeTextElement("Weight", "1.0");
    writer.writeEmptyElement("Label");
    attributes.clear();
    attributes.append("name", "(1)cha");
    attributes.append("color", "#0cc8f3");
    attributes.append("number", "1");
    writer.writeAttributes(attributes);
    writer.writeEndElement();
    writer.writeStartElement("SubDir");
    attributes.clear();
    attributes.append("itemText", "BG-CHA(4222/4222)");
    attributes.append("dirBaseName", "BG-CHA");
    attributes.append("withSubDir", "false");
    attributes.append("showSubDir", "false");
    writer.writeAttributes(attributes);
    writer.writeTextElement("ImageSum", "4222");
    writer.writeEmptyElement("DirInfo");
    attributes.clear();
    attributes.append("dirFullName", "/home/liuqiang/Documents/BG/train/BG-CHA");
    attributes.append("imageNumber", "4222");
    writer.writeAttributes(attributes);
    writer.writeTextElement("Weight", "1.0");
    writer.writeEmptyElement("Label");
    attributes.clear();
    attributes.append("name", "(1)cha");
    attributes.append("color", "#0cc8f3");
    attributes.append("number", "1");
    writer.writeAttributes(attributes);
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeComment("第4行的配置数据保存完毕!");

    writer.writeEndElement();
    file.close();
}

第2步:使用QXmlStreamReader实现xml文件的读取操作

void readXML() {
    QFile file("../generateConfigureInfoFile/bg_train01.xml");
    if(!file.open(QFile::ReadOnly | QFile::Text)) {
        qDebug() << "failed to open bg_train01.xml";
        return;
    }
    QXmlStreamReader reader;
    reader.setDevice(&file);
    reader.readNext();
    if(reader.isStartDocument()){
        QString version = reader.documentVersion().toString();
        QString encoding = reader.documentEncoding().toString();
        bool isAlone = reader.isStandaloneDocument();
        qDebug() << "Version: " << version << "; Encoding: " << encoding << "Standalone: " << isAlone;
        reader.readNext();
    }
    while (!reader.atEnd()) { //如果没有读到文档结尾,而且没有出现错误
        if(reader.isStartElement()) {
            if(reader.name() == "ConfigInfo") {
                 qDebug() << "start reading: " << reader.name();
                 reader.readNext();
            }
            else if(reader.name() == "RootDir") {
                qDebug() << reader.name()
                         << reader.attributes().value("itemText")
                         << reader.attributes().value("dirBaseName")
                         << reader.attributes().value("withSubDir")
                         << reader.attributes().value("showSubDir");
                reader.readNext();
            }
            else if(reader.name() == "SubDir") {
                qDebug() << reader.name()
                         << reader.attributes().value("itemText")
                         << reader.attributes().value("dirBaseName")
                         << reader.attributes().value("withSubDir")
                         << reader.attributes().value("showSubDir");
                reader.readNext();
            }
            else if(reader.name() == "ImageSum") {
                qDebug() << reader.name() << reader.readElementText().toInt();
                reader.readNext();
            }
            else if(reader.name() == "DirInfo") {
                qDebug() << reader.name() << reader.attributes().value("dirFullName")
                         << reader.attributes().value("imageNumber");
                reader.readNext();
            }
            else if(reader.name() == "Weight") {
                qDebug() << reader.name() << reader.readElementText().toFloat();
                reader.readNext();
            }
            else if(reader.name() == "Label") {
                qDebug() << reader.name()
                         << reader.attributes().value("name")
                         << reader.attributes().value("color")
                         << reader.attributes().value("number");
                reader.readNext();
            }
            else {
                reader.readNext();
            }
        }
        else if(reader.isComment()) {
            qDebug() << reader.text(); //读取注释内容
            reader.readNext();
        }
        else if(reader.isEndElement()) {
            reader.readNext();
        }
        else {
            reader.readNext();
        }
        if (reader.hasError()) { //如果读取过程中出现错误,那么输出错误信息
            qDebug() << "error: " << reader.errorString();
        }
    }
    file.close();
}

调用写入和解析函数

int main() {
    writeXML();
    readXML();
    return 0;
}

在我的机器上运行结果如下:
使用QXmlStreamWriter写入的结果截图:
在这里插入图片描述
使用QXmlStreamReader读取的结果截图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值