Qt学习笔记(Qt读写 XML文件 )

2022年01月13日 阅读数:3
这篇文章主要向大家介绍Qt学习笔记(Qt读写 XML文件 ),主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

XML文件通常格式以下:html

<?xml version='1.0' encoding='UTF-8'?>
<--注释:除了第一行,随便写 有头有尾 有开始标签就有闭合标签 -->
<root 有头有尾/>

<root>
 xml优势是比较灵活 
 html5不少标签都是固定的
 设定规则主要是用来存储数据,标签能够任意定义
 保存数据库很轻松
 文本文件1##mike##female##10 把数据存储在文本文件中不美观
 xml存储数据很人性化
 之前的操做系统对数据库支持很差,存储数据用xml
 安卓手机根目录下,存储一些数据也用xml
 网络上能够组xml传输数据
 xml主要用于存储数据,作配置文件
 html5主要用于显示数据

 xml中,根节点有且仅有一个
 xml中,子节点能够有任意个
 Qt中平时作ui,每次对ui修改,都会自动修改对应的.ui(实际上上.xml文件)文件

</root>

<info>
  <stu id="1">
       <name>mike</name>   //元素  node--》元素
       <sex>female</sex>
       <score>10</score>
 </stu>
<stu id="2">
       <name>mike</name>
       <sex>female</sex>
       <score>10</score>
 </stu>
</info>

Qt源文件: html5

//xmltest.pro
QT       += core gui sql xml

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    domxml.cpp \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    domxml.h \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
//domxml.h
#ifndef DOCXML_H
#define DOCXML_H
#include <QString>
#include <QStringList>
#include <QDomDocument>
#include <QDomElement>

class DomXML
{
public:
    DomXML();

   static void createXML(QString filePath);//建立xml空文件
   //静态不须要经过对象来调用

   static void appendXML(QString filePath,QStringList list);
    //list.at(0)=二汽神龙
   static void  writeXML(QDomDocument &doc,QDomElement &root,QStringList &list);

   static void  readXML(QString filePath,
                        QStringList &fList,
                        QStringList &bList,
                        QStringList &pList,
                        QStringList &nList,
                        QStringList &tList
                        );

};

#endif // DOCXML_H
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//domxml.cpp
#include "domxml.h"
#include <QFile>
#include <QDomDocument>//xml文件指针
#include <QDomProcessingInstruction> //格式头部
#include <QDomElement>  //元素
#include <QDebug>
#include <QDateTime> //日期时间
#define cout qDebug()<<"["<<__FILE__<<":"<<__LINE__<<"]"
#include <QTextStream>
//appendChild()追加
DomXML::DomXML()
{

}

void DomXML::createXML(QString filePath){
    QFile file(filePath);//关联文件名字
    if(true==file.exists()){//若是存在不建立
        cout<<"文件已经存在";
        return;
    }
    else{
        //不存在才建立
         //只写方式打开文件
         bool isOK=file.open(QIODevice::WriteOnly);
         if(true==isOK){//若是打开成功
             //建立xml文档对象
             QDomDocument doc;

             //建立xml头部格式
             QDomProcessingInstruction ins;

             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<<"WriteOnly error";
             return;
         }
    }
}
void DomXML::appendXML(QString filePath, QStringList list){
    QFile file(filePath);
    bool isOk=file.open(QIODevice::ReadOnly);
    if(true==isOk)//打开成功
    {
        //操做xml必定要有一个文档指针。
        //file和xml文档对象关联
        QDomDocument doc;
        isOk=doc.setContent(&file);
        if(isOk){//若是关联成功
            file.close();//关闭文件
            //获取根节点元素
            QDomElement root=doc.documentElement();

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

            //判断根节点下有没有子节点
            if(root.hasChildNodes()){//若是有子节点

                //xml里存储了不少信息,若是再次存入的是当天的信息则采用在当天日期元素下追加一个时间节点
                //不然新建一个日期节点元素



                //查找最后一个子节点
                QDomElement lastEmt=root.lastChildElement();
                if(lastEmt.attribute("date")==dateStr){
                    //有当天日期

                    writeXML(doc,lastEmt,list);//在下边添加时间



                }else{
                      //没有当天日期,copy下边代码 复用一下
                    //建立日期子节点元素
                    QDomElement dateEmt=doc.createElement("日期");
                    //建立date属性
                    QDomAttr dateAttr=doc.createAttribute("date");
                    //设定属性的值
                    dateAttr.setNodeValue(dateStr);
                    //节点和属性关联
                    dateEmt.setAttributeNode(dateAttr);

                    //最重要的一步,把日期节点追加到根节点上
                    root.appendChild(dateEmt);

                    //写有效数据  文档,元素,内容
                    writeXML(doc,dateEmt,list);


                }


            }else{//没有子节点
                //建立日期子节点元素
                QDomElement dateEmt=doc.createElement("日期");
                //建立date属性
                QDomAttr dateAttr=doc.createAttribute("date");
                //设定属性的值
                dateAttr.setNodeValue(dateStr);
                //节点和属性关联
                dateEmt.setAttributeNode(dateAttr);

                //最重要的一步,把日期节点追加到根节点上
                root.appendChild(dateEmt);

                //写有效数据  文档,元素,内容
                writeXML(doc,dateEmt,list);

            }
            //保存文件
            isOk=file.open(QIODevice::WriteOnly);
            if(isOk){
                QTextStream stream(&file);
                doc.save(stream,4);
            }

        }else{
            cout<<"setContent error";
            return;
        }



    }else{
        cout<<"ReadOnly error ";
    }

}

void DomXML::writeXML(QDomDocument &doc, QDomElement &root, QStringList &list){
    //当前时间获取
    QDateTime time=QDateTime::currentDateTime();
    QString timeStr=time.toString("hh-mm-ss");//14:03:03
    //建立时间节点元素
    QDomElement timeEmt=doc.createElement("时间");
    //建立属性
    QDomAttr timeAttr=doc.createAttribute("time");
    //给属性设置值
    timeAttr.setNodeValue(timeStr);
    //时间节点元素和属性关联
    timeEmt.setAttributeNode(timeAttr);
    //把时间节点追加到日期节点后面
    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);



}
void DomXML::readXML(QString filePath, QStringList &fList, QStringList &bList, QStringList &pList, QStringList &nList, QStringList &tList){
    QFile file(filePath);
    bool isOk=file.open(QIODevice::ReadOnly);
    if(true==isOk)//打开成功
    {
        //操做xml必定要有一个文档指针。
        //file和xml文档对象关联
        QDomDocument doc;
        isOk=doc.setContent(&file);
        if(isOk){//若是关联成功
            //获取根节点
            QDomElement root=doc.documentElement();
            //成功以后能够把文件关闭
            file.close();

            QDateTime date=QDateTime::currentDateTime();
            QString dateStr=date.toString("yyyy-MM-dd");

            if(root.hasChildNodes()){//有子节点
                //找到最后一个元素
                QDomElement lastEmt=root.lastChildElement();
                if(lastEmt.attribute("date")==dateStr){//判断有没有当前日期
                   //找出当前日期下全部时间子节点
                    QDomNodeList list = lastEmt.childNodes();
                    //list.at(0);
                    for(int i=0;i<list.size();i++){
                       // list.at(0).toElement();
                        //转化成元素,找到咱们时间下的全部子节点
                        QDomNodeList subList=list.at(i).toElement().childNodes();
                        //厂家
                        QString factory=subList.at(0).toElement().text();
                        fList.append(factory);

                        QString brand=subList.at(1).toElement().text();
                        bList.append(brand);

                        QString price=subList.at(2).toElement().text();
                        pList.append(price);

                        QString num=subList.at(3).toElement().text();
                        nList.append(num);

                        QString total=subList.at(4).toElement().text();
                        tList.append(total);


                    }

                }else{
                    cout<<"没有当天日期";
                    return;
                }

            }
            else
            {
                cout<<"没有子节点";
                return;
            }
        }else{
            cout<<"SetContent error";
            return;
        }
    }else{
        cout<<"ReadOnly error";
        return;
    }

}
//main.cpp
#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "domxml.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);



   DomXML::createXML("../demo.xml");//建立一个空的xml文件
    QStringList list;
    list<<"二汽神龙"<<"毕加索"<<"39"<<"1"<<"39";
   DomXML::appendXML("../demo.xml",list);

    QStringList fList;
    QStringList bList;
    QStringList pList;
    QStringList nList;
    QStringList tList;

    DomXML::readXML("../demo.xml",fList,bList,pList,nList,tList);
    for(int i=0;i<fList.size();i++){
       QString str=QString("%1:%2:卖出了%3,单价为:%4,总价为:%5")
               .arg(fList.at(i))
               .arg(bList.at(i))
               .arg(nList.at(i))
               .arg(pList.at(i))
               .arg(tList.at(i));
       qDebug()<<str.toUtf8().data()<<endl;//转换一下编码



    }



}

MainWindow::~MainWindow()
{
    delete ui;
}
<--mainwindow.ui-->
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget"/>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>