Dom 对 xml 的读写操作

本文详细介绍如何在Qt中使用QtXml模块进行XML文档的创建、读取和更新操作,包括DOM方法的应用,以及通过具体实例展示XML文档的增删改查功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

XML(ExtensibleMarkup Language,可扩展标记语言),是一种类似于HTML的标记语言,但它的设计目的是用来传输数据,而不是显示数据。XML的标签没有被预定义,用户需要在使用时自行进行定义。XML是W3C(万维网联盟)的推荐标准。相对于数据库表格的二维表示,XML使用的树形结构更能表现出数据的包含关系,作为一种文本文件格式,XML简单明了的特性使得它在信息存储和描述领域非常流行。

在Qt中提供了QtXml模块来进行XML文档的处理,我们在Qt帮助中输入关键字QtXml Module,可以看到该模块的类表。这里主要提供了三种解析方法: DOM方法,可以进行读写;SAX方法,可以进行读取;基于流的方法,分别使用QXmlStreamReader和QXmlStreamWriter进行读取和写入。要在项目中使用QtXml模块,还需要在项目文件(.pro文件)中添加QT += xml一行代码。

新建一个项目
ui 界面
在这里插入图片描述
pro 文件

QT       += core gui xml

.h 文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void doXml(const QString operate);
private slots:
    void on_pushButton_search_clicked();
    void on_pushButton_delete_clicked();
    void on_pushButton_update_clicked();
    void on_pushButton_add_clicked();
    void on_pushButton_selectAll_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

.cpp 文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtXml>
#include <QFile>
#include <QDomComment>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QFile file("my.xml");
    if(!file.open(QIODevice::WriteOnly |QIODevice::Truncate))
    {
        return;
    }
    QDomDocument doc;
    QDomProcessingInstruction instruction;  //添加处理指令
    instruction = doc.createProcessingInstruction("xml","version=\"1.0\"encoding=\"UTF-8\"");
    doc.appendChild(instruction);
    QDomElement root = doc.createElement(tr("书库"));
    doc.appendChild(root); //添加根元素

    // 添加第一个book元素及其子元素
    QDomElement book = doc.createElement(tr("图书"));
    QDomAttr id = doc.createAttribute(tr("编号"));
    QDomElement title = doc.createElement(tr("书名"));
    QDomElement author = doc.createElement(tr("作者"));
    QDomText text;
    id.setValue(tr("1"));
    book.setAttributeNode(id);
    text = doc.createTextNode(tr("Qt"));
    title.appendChild(text);
    text = doc.createTextNode(tr("shiming"));
    author.appendChild(text);
    book.appendChild(title);
    book.appendChild(author);
    root.appendChild(book);

    // 添加第二个book元素及其子元素
    book = doc.createElement(tr("图书"));
    id = doc.createAttribute(tr("编号"));
    title = doc.createElement(tr("书名"));
    author = doc.createElement(tr("作者"));
    id.setValue(tr("2"));
    book.setAttributeNode(id);
    text = doc.createTextNode(tr("Linux"));
    title.appendChild(text);
    text = doc.createTextNode(tr("yafei"));
    author.appendChild(text);
    book.appendChild(title);
    book.appendChild(author);
    root.appendChild(book);

    QTextStream out(&file);
    doc.save(out,4); // 将文档保存到文件,4为子元素缩进字符数
    file.close();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::doXml(const QString operate)
{
    ui->listWidget->clear();
     ui->listWidget->addItem(tr("没有找到相关内容!"));
     QFile file("my.xml");
     if (!file.open(QIODevice::ReadOnly)) return ;
     QDomDocument doc;
     if (!doc.setContent(&file))
     {
        file.close();
        return ;
     }
        file.close();

     QDomNodeList list = doc.elementsByTagName(tr("图书"));
     // 以标签名进行查找
     for(int i=0; i<list.count(); i++)
     {
        QDomElement e = list.at(i).toElement();
        // 如果元素的“编号”属性值与我们所查的相同
        if(e.attribute(tr("编号")) == ui->lineEdit_id->text())
        {
             // 如果元素的“编号”属性值与我们所查的相同
            if(operate == "delete")  //如果是删除操作
            {
                 QDomElement root = doc.documentElement(); //取出根节点
                 root.removeChild(list.at(i));  //从根节点上删除该节点
                 QFile file("my.xml");     //保存更改
           if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
                                     return ;
                 QTextStream out(&file);
                 doc.save(out,4);
                 file.close();
                 ui->listWidget->clear();
                 ui->listWidget->addItem(tr("删除成功!"));
            }
            else if(operate == "update")  //如果是更新操作
            {
                 QDomNodeList child = list.at(i).childNodes();
                 //找到它的所有子节点,就是“书名”和“作者”
                 child.at(0).toElement().firstChild().setNodeValue(ui->lineEdit_title->text());
                 //将它子节点的首个子节点(就是文本节点)的内容更新
                 child.at(1).toElement().firstChild().setNodeValue(ui->lineEdit_author->text());
                 QFile file("my.xml");     //保存更改
           if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
                                    return ;
                 QTextStream out(&file);
                 doc.save(out,4);   //保存文档,4为子元素缩进字符数
                 file.close();
                 ui->listWidget->clear();
                 ui->listWidget->addItem(tr("更新成功!"));
            }
            else if(operate == "find")  //如果是查找操作
            {
                 ui->listWidget->clear();
                 ui->listWidget->addItem(e.tagName()+e.attribute(tr("编号")));
                 QDomNodeList list = e.childNodes();
                 for(int i=0; i<list.count(); i++)
                {
                     QDomNode node = list.at(i);
                     if(node.isElement())
                         ui->listWidget->addItem("   "+node.toElement().tagName()
                                  +" : "+node.toElement().text());
                 }
            }
        }
     }
}

void MainWindow::on_pushButton_search_clicked()
{
    doXml("find");
}

void MainWindow::on_pushButton_delete_clicked()
{
     doXml("delete");
}

void MainWindow::on_pushButton_update_clicked()
{
     doXml("update");
}

void MainWindow::on_pushButton_add_clicked()
{
    ui->listWidget->clear(); //我们先清空显示,然后显示“无法添加!”
    ui->listWidget->addItem(tr("无法添加!"));
    QFile file("my.xml");
    if (!file.open(QIODevice::ReadOnly)) return;
    QDomDocument doc;
    if (!doc.setContent(&file))
    {
       file.close();
       return;
    }
    file.close();
    QDomElement root = doc.documentElement();
    QDomElement book = doc.createElement(tr("图书"));
    QDomAttr id = doc.createAttribute(tr("编号"));
    QDomElement title = doc.createElement(tr("书名"));
    QDomElement author = doc.createElement(tr("作者"));
    QDomText text;
    // 我们获得了最后一个孩子结点的编号,然后加1,便是新的编号
    QString num = root.lastChild().toElement().attribute(tr("编号"));
    int count = num.toInt() +1;
    id.setValue(QString::number(count));
    book.setAttributeNode(id);
    text = doc.createTextNode(ui->lineEdit_title->text());
    title.appendChild(text);
    text = doc.createTextNode(ui->lineEdit_author->text());
    author.appendChild(text);
    book.appendChild(title);
    book.appendChild(author);
    root.appendChild(book);
    if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
       return ;
    QTextStream out(&file);
    doc.save(out,4);   //将文档保存到文件,4为子元素缩进字符数
    file.close();
    ui->listWidget->clear(); //最后更改显示为“添加成功!”
    ui->listWidget->addItem(tr("添加成功!"));
}

//读取所有的数据
void MainWindow::on_pushButton_selectAll_clicked()
{
    ui->listWidget->clear();
    QFile file("my.xml");
    if(!file.open(QIODevice::ReadOnly)){
        return;
    }
    QDomDocument doc;
     if (!doc.setContent(&file))
     {
       file.close();
       return ;
    }
    file.close();

    //返回根节点及其子节点的元素标记名
    QDomElement docElem = doc.documentElement();  //返回根元素
    QDomNode n = docElem.firstChild();   //返回根节点的第一个子节点
    while(!n.isNull())  //如果节点不为空
    {
        if (n.isElement()) //如果节点是元素
       {
           QDomElement e = n.toElement(); //将其转换为元素
           ui->listWidget->addItem(e.tagName()+e.attribute(tr("编号")));
           QDomNodeList list = e.childNodes();
           for(int i=0; i<list.count(); i++)
           {
                QDomNode node = list.at(i);
                if(node.isElement())
                   ui->listWidget->addItem("   "+node.toElement().tagName()+" : "+node.toElement().text());
           }
       }
       n = n.nextSibling();  //下一个兄弟节点
    }
}

运行界面如下
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值