一、XML简介:
XML, 全称为扩展标记语言, 可用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据,是Internet环境中跨平台的、依赖于内容的技术,也是当今处理分布式结构信息的有效工具。XML常用于接口调用,配置文件,数据存储等场景。
二、XML解析技术:
1)dom (Document Object Model)
将整个文档当作一个对象装入内存进行处理,根据xml的层级结构,在内存中分配一个树形结构,把xml中的每部分都封装成对象,开发者可以访问这个对象中得每一个节点,每一个节点对应XML文件里得一个标记。
      优点:方便实现增删查改操作
       缺点:如果文件过大时,造成内存溢出
      实现类:QDomDocument
       .Pro文件加上 QT += xml
      使用示例:
             QDomDocument doc(“mydocument”);
             QFile file(“mydocument.xml”);
             if (!file.open(QIODevice::ReadOnly))
             return;
             if (!doc.setContent(&file))
             {
                  file.close();
                  return;
             }
             file.close();
通过setContent将指定的内容指定给QDomDocument解析,解析成功得到一个完整的QDomDocument对象doc,只要访问doc的节点就能得到XML上的内容。
2)sax (Simple API for XML)
按阶段将文档读取到内存中,进行边读边解析,从上到下,一行一行解析对象,返回对象名称。
      优点:不存在内存溢出,方便实现查询
       缺点:不便于随机访问任意节点
实现类:QXmlSimpleReader
      使用示例:
             QFile file(“mydocument.xml”);
             QXmlStreamReader xmlRead; //创建一个类对象
             xmlRead.setDevice(&file); //通过setDevice设置要处理的XML文件
             if(xmlRead.readNextStartElement()) //挨个读入节点
             {
                 if(xmlRead.name().toString() == “root”)
                 {
                     if(xmlRead.readNextStartElement())
                     {
                         if(xmlRead.name().toString() == “config”)
                         {
                             …
                         }
                     }
                 }
             }
三、CSV与XML的区别:
1)CSV
      格式语法不同,CSV每条记录占一行,以逗号为分隔符,逗号前后的空格会被忽略。
 CSV格式很简单。 它具有包含类别和术语及其属性值(例如描述,缩写和自定义属性值)的功能。 它还使您能够定义管家关系。
2)XML
XML格式更全面,更复杂。 它具有定义术语,类别和其他对象类型(包括与其他术语有关的术语,与术语有关的类别,链接到已分配资产的术语)之间的每种可能关系的功能。
四、XML读写demo:
1)界面

2)核心代码
ctxml.h
#ifndef CTXML_H
#define CTXML_H
#include <QObject>
#include "commondef.h"
class CtXml : public QObject
{
    Q_OBJECT
public:
    CtXml();
    ~CtXml();
    static CtXml& getInstance();
signals:
    void sig_returnXmlData(PERSION_T stPersion);
public slots:
    void on_writeToXmlFileWithDom(PERSION_T stPersion);
    void on_readFromXmlFileWithDom();
    void on_writeToXmlFileWithSax(PERSION_T stPersion);
    void on_readFormXmlFileWithSax();
};
#endif // CTXML_H
 
ctxml.cpp
#include "ctxml.h"
#include <QDomDocument>
#include <QFile>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
CtXml::CtXml()
{
}
CtXml::~CtXml()
{
}
CtXml &CtXml::getInstance()
{
    static CtXml s_obj;
    return s_obj;
}
void CtXml::on_writeToXmlFileWithDom(PERSION_T stPersion)
{
    QDomDocument dDoc;
    QString sHeader("version=\"1.0\" encoding=\"UTF-8\"");
    dDoc.appendChild(dDoc.createProcessingInstruction("xml", sHeader));//生成说明
    //生成根节点
    QDomElement sRootElement = dDoc.createElement("Root");
    dDoc.appendChild(sRootElement);
    QDomElement PersionElement = dDoc.createElement("Persion");
    QDomElement Item1Element = dDoc.createElement("Item");
    Item1Element.setAttribute("Name", "Name");
    Item1Element.setAttribute("Type", "QString");
    QDomText Item1Text = dDoc.createTextNode("Item");
    Item1Text.setData(stPersion.sName);
    Item1Element.appendChild(Item1Text);
    PersionElement.appendChild(Item1Element);
    QDomElement Item2Element = dDoc.createElement("Item");
    Item2Element.setAttribute("Name", "Age");
    Item2Element.setAttribute("Type", "Int");
    QDomText Item2Text = dDoc.createTextNode("Item");
    Item2Text.setData(QString::number(stPersion.nAge));
    Item2Element.appendChild(Item2Text);
    PersionElement.appendChild(Item2Element);
    QDomElement Item3Element = dDoc.createElement("Item");
    Item3Element.setAttribute("Name", "Sex");
    Item3Element.setAttribute("Type", "QString");
    QDomText Item3Text = dDoc.createTextNode("Item");
    Item3Text.setData(stPersion.Sex);
    Item3Element.appendChild(Item3Text);
    PersionElement.appendChild(Item3Element);
    QDomElement Item4Element = dDoc.createElement("Item");
    Item4Element.setAttribute("Name", "Height");
    Item4Element.setAttribute("Type", "Int");
    QDomText Item4Text = dDoc.createTextNode("Item");
    Item4Text.setData(QString::number(stPersion.nHeight));
    Item4Element.appendChild(Item4Text);
    PersionElement.appendChild(Item4Element);
    QDomElement Item5Element = dDoc.createElement("Item");
    Item5Element.setAttribute("Name", "Weight");
    Item5Element.setAttribute("Type", "Int");
    QDomText Item5Text = dDoc.createTextNode("Item");
    Item5Text.setData(QString::number(stPersion.nWeight));
    Item5Element.appendChild(Item5Text);
    PersionElement.appendChild(Item5Element);
    sRootElement.appendChild(PersionElement);
    QFile file(XML_FILE_PATH);
    if(!file.open(QFile::WriteOnly | QFile::Text | QFile :: Truncate))//Truncate:覆盖重写
    {
        MY_DEBUG << "Open XML File Failed";
        return;
    }
    file.write(dDoc.toString().toLocal8Bit().data());
    file.close();
}
void CtXml::on_readFromXmlFileWithDom()
{
    QDomDocument dDoc;
    QFile file(XML_FILE_PATH);
    if(!file.open(QFile::ReadOnly | QFile::Text))
    {
        MY_DEBUG << "Open XML File Failed";
        return;
    }
    int iErrorLine;
    int iErrorCol;
    QString sErrorMsg;
    if (!dDoc.setContent(&file, false, &sErrorMsg, &iErrorLine, &iErrorCol))
    {
        sErrorMsg = QString::fromLocal8Bit("Parse Failed.");
        MY_DEBUG << "sErrorMsg:" << sErrorMsg;
        file.close();
        return;
    }
    file.close();
    PERSION_T stPersion;
    QDomElement deRootNode = dDoc.documentElement();
    if(deRootNode.tagName() == "Root")
    {
        MY_DEBUG << "readFromXmlFileWithDom 000";
        QDomNode PersionNode = deRootNode.firstChild();
        while(!PersionNode.isNull())
        {
            MY_DEBUG << "readFromXmlFileWithDom 111";
            QString sPersion = PersionNode.toElement().tagName();
            if(!sPersion.compare("Persion"))
            {
                MY_DEBUG << "readFromXmlFileWithDom 222";
                QDomNodeList ItemNodeList = PersionNode.childNodes();
                for(int i = 0; i < ItemNodeList.size(); i++)
                {
                    MY_DEBUG << "readFromXmlFileWithDom 333";
                    QDomElement ItemElement = ItemNodeList.at(i).toElement();
                    if(!ItemElement.tagName().compare("Item"))
                    {
                        MY_DEBUG << "readFromXmlFileWithDom 444";
                        if(ItemElement.hasAttribute("Name"))
                        {
                            MY_DEBUG << "readFromXmlFileWithDom 555";
                            QString str = ItemElement.attribute("Name");
                            if(!str.compare("Name"))
                            {
                                stPersion.sName = ItemElement.text();
                            }
                            else if(!str.compare("Age"))
                            {
                                stPersion.nAge = ItemElement.text().toInt();
                            }
                            else if(!str.compare("Sex"))
                            {
                                stPersion.Sex = ItemElement.text();
                            }
                            else if(!str.compare("Height"))
                            {
                                stPersion.nHeight = ItemElement.text().toInt();
                            }
                            else if(!str.compare("Weight"))
                            {
                                stPersion.nWeight = ItemElement.text().toInt();
                            }
                        }
                    }
                }
            }
            PersionNode = PersionNode.nextSibling();
        }
    }
    emit sig_returnXmlData(stPersion);
}
void CtXml::on_writeToXmlFileWithSax(PERSION_T stPersion)
{
    QFile file(XML_FILE_PATH2);
    if(!file.open(QFile::WriteOnly | QFile::Text | QFile :: Truncate))
    {
        MY_DEBUG << "XML File Open Failed.";
        return;
    }
    QXmlStreamWriter xmlWrite(&file);
    xmlWrite.setAutoFormatting(true);
    xmlWrite.writeStartDocument("1.0",true);
    xmlWrite.writeStartElement("Root");
    xmlWrite.writeStartElement("Persion");
    xmlWrite.writeStartElement ("Item");
    xmlWrite.writeAttribute("Name","Name");
    xmlWrite.writeAttribute("Type","QString");
    xmlWrite.writeCharacters(stPersion.sName);
    xmlWrite.writeEndElement();
    xmlWrite.writeStartElement ("Item");
    xmlWrite.writeAttribute("Name","Age");
    xmlWrite.writeAttribute("Type","Int");
    xmlWrite.writeCharacters(QString::number(stPersion.nAge));
    xmlWrite.writeEndElement();
    xmlWrite.writeStartElement ("Item");
    xmlWrite.writeAttribute("Name","Sex");
    xmlWrite.writeAttribute("Type","QString");
    xmlWrite.writeCharacters(stPersion.Sex);
    xmlWrite.writeEndElement();
    xmlWrite.writeStartElement ("Item");
    xmlWrite.writeAttribute("Name","Height");
    xmlWrite.writeAttribute("Type","Int");
    xmlWrite.writeCharacters(QString::number(stPersion.nHeight));
    xmlWrite.writeEndElement();
    xmlWrite.writeStartElement ("Item");
    xmlWrite.writeAttribute("Name","Weight");
    xmlWrite.writeAttribute("Type","Int");
    xmlWrite.writeCharacters(QString::number(stPersion.nWeight));
    xmlWrite.writeEndElement();
    xmlWrite.writeEndElement();    //Persion结束
    xmlWrite.writeEndElement();    //Root结束
    xmlWrite.writeEndDocument();   //Document结束
    file.close();
}
void CtXml::on_readFormXmlFileWithSax()
{
    QFile file(XML_FILE_PATH2);
    if(!file.open(QFile::ReadOnly | QFile::Text))
    {
        MY_DEBUG << "XML File Open Failed.";
        return;
    }
    PERSION_T stPersion;
    QXmlStreamReader xmlRead;
    xmlRead.setDevice(&file);
    if(xmlRead.readNextStartElement())
    {
        if(xmlRead.name().toString() == "Root")
        {
           if(xmlRead.readNextStartElement())
           {
               if(xmlRead.name().toString() == "Persion")
               {
                   while(xmlRead.readNextStartElement()) //循环读取Item
                   {
                      if(xmlRead.name().toString() == "Item")
                      {
                          QXmlStreamAttributes attributes = xmlRead.attributes();
                          if(attributes.hasAttribute("Name"))
                          {
                              QString sName = attributes.value("Name").toString();
                              if(!sName.compare("Name"))
                              {
                                  stPersion.sName = xmlRead.readElementText();
                              }
                              else if(!sName.compare("Age"))
                              {
                                  stPersion.nAge = xmlRead.readElementText().toInt();
                              }
                              else if(!sName.compare("Sex"))
                              {
                                  stPersion.Sex = xmlRead.readElementText();
                              }
                              else if(!sName.compare("Height"))
                              {
                                  stPersion.nHeight = xmlRead.readElementText().toInt();
                              }
                              else if(!sName.compare("Weight"))
                              {
                                  stPersion.nWeight = xmlRead.readElementText().toInt();
                              }
                              else
                              {
                                  xmlRead.readNextStartElement();
                              }
                          }
                      }
                   }
               }
           }
        }
    }
    emit sig_returnXmlData(stPersion);
}
 
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "commondef.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
signals:
    void sig_writeToXmlFileWithDom(PERSION_T stPersion);
    void sig_readFromXmlFileWithDom();
    void sig_writeToXmlFileWithSax(PERSION_T stPersion);
    void sig_readFormXmlFileWithSax();
public slots:
    void on_returnXmlData(PERSION_T stPersion);
private slots:
    void on_pushButton_Save_Dom_clicked();
    void on_pushButton_Read_Dom_clicked();
    void on_pushButton_Save_Sax_clicked();
    void on_pushButton_Read_Sax_clicked();
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_
 
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "ctxml.h"
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    qRegisterMetaType<PERSION_T>("PERSION_T");
    connect(&CtXml::getInstance(), SIGNAL(sig_returnXmlData(PERSION_T)),
            this, SLOT(on_returnXmlData(PERSION_T)));
    connect(this, SIGNAL(sig_writeToXmlFileWithDom(PERSION_T)),
            &CtXml::getInstance(), SLOT(on_writeToXmlFileWithDom(PERSION_T)));
    connect(this, SIGNAL(sig_readFromXmlFileWithDom()),
            &CtXml::getInstance(), SLOT(on_readFromXmlFileWithDom()));
    connect(this, SIGNAL(sig_writeToXmlFileWithSax(PERSION_T)),
            &CtXml::getInstance(), SLOT(on_writeToXmlFileWithSax(PERSION_T)));
    connect(this, SIGNAL(sig_readFormXmlFileWithSax()),
            &CtXml::getInstance(), SLOT(on_readFormXmlFileWithSax()));
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_returnXmlData(PERSION_T stPersion)
{
    ui->lineEdit_Age->setText(QString::number(stPersion.nAge));
    ui->lineEdit_Sex->setText(stPersion.Sex);
    ui->lineEdit_Name->setText(stPersion.sName);
    ui->lineEdit_Height->setText(QString::number(stPersion.nHeight));
    ui->lineEdit_Weight->setText(QString::number(stPersion.nWeight));
}
void MainWindow::on_pushButton_Save_Dom_clicked()
{
    PERSION_T stPersion;
    stPersion.Sex = ui->lineEdit_Sex->text();
    stPersion.nAge = ui->lineEdit_Age->text().toInt();
    stPersion.sName = ui->lineEdit_Name->text();
    stPersion.nHeight = ui->lineEdit_Height->text().toInt();
    stPersion.nWeight = ui->lineEdit_Weight->text().toInt();
    emit sig_writeToXmlFileWithDom(stPersion);
    QMessageBox::information(this, "Tip", "Save Xml With Dom Success.");
}
void MainWindow::on_pushButton_Read_Dom_clicked()
{
    emit sig_readFromXmlFileWithDom();
}
void MainWindow::on_pushButton_Save_Sax_clicked()
{
    PERSION_T stPersion;
    stPersion.Sex = ui->lineEdit_Sex->text();
    stPersion.nAge = ui->lineEdit_Age->text().toInt();
    stPersion.sName = ui->lineEdit_Name->text();
    stPersion.nHeight = ui->lineEdit_Height->text().toInt();
    stPersion.nWeight = ui->lineEdit_Weight->text().toInt();
    emit sig_writeToXmlFileWithSax(stPersion);
    QMessageBox::information(this, "Tip", "Save Xml With Sax Success.");
}
void MainWindow::on_pushButton_Read_Sax_clicked()
{
    emit sig_readFormXmlFileWithSax();
}
 
3)demo工程下载
下载地址链接:https://download.csdn.net/download/linyibin_123/87374629



















