Qt中使用DOM读写XML文档

需要在.pro文件添加QT += xml
DOM(Document Object Model)可以将XML文档读入到内存中进而显示和修改,相当于一个缓冲区。文档由QDomDocument表示,所有DOM节点都是QDomNode的子类

创建XML
一 创建 QDomDocument doc;
二 创建处理指令
三 创建根元素(根元素及其包含的元素其实都是QDomElement)
四 创建第一个元素及其子元素~~~~

1 创建元素
2 创建属性(还可以赋值)
3 给元素设置属性节点 `book.setAttributeNode(id);`

4 创建子元素
5 创建文本节点
6 给子元素附加文本子节点 `title.appendChild(text);`

7 给元素附加子元素节点 `book.appendChild(title);`
8 给根元素附加子节点 `root.appendChild(book);`

9 创建文件以只写模式打开并关联到文本流 `QTextStream out(&file);`
10 保存,4为子元素缩进字符数 `doc.save(out, 4);`然后关闭文件

读取XML
一 创建 QDomDocument doc;
二 只读打开文件内容到doc然后关闭文件
三 创建并获取节点 QDomNode docNode = doc.documentElement().firstChild();
四 判断创建的节点非空
五 跳过处理指令 if (docNode.isElement())
六 将格式从节点转为元素
七 读取元素名称等信息
八 创建节点列表读入元素的所有子节点 QDomNodeList list = elem.childNodes();
九 判断是否为元素,转格式,读取信息
十 更新docNode到下一个节点~~~~

写入XML:增
一 创建 QDomDocument doc;
二 只读打开文件内容到doc然后关闭文件
三 创建、获取根元素及其最后子元素编号
四 创建新元素设置属性节点
五 创建子元素、文本
六 文本附加到子元素,子元素附加到新元素,新元素附加到根元素
七 只写截断打开文件,关联到文本流
八 保存文件,关闭文件

写入XML:删
一 创建 QDomDocument doc;
二 只读打开文件内容到doc然后关闭文件
三 以标签名查找元素节点 QDomNodeList list = doc.elementsByTagName("图书");
四 按属性逐个比对
五 从根元素删除目标元素,保存

写入XML:改
一 创建 QDomDocument doc;
二 只读打开文件内容到doc然后关闭文件
三 以标签名查找元素节点 QDomNodeList list = doc.elementsByTagName("图书");
四 按属性逐个比对
五 获取目标节点的子节点 QDomNodeList child = list.at(i).childNodes();
六 修改信息,保存

写入XML:查
一 创建 QDomDocument doc;
二 只读打开文件内容到doc然后关闭文件
三 以标签名查找元素节点 QDomNodeList list = doc.elementsByTagName("图书");
四 按属性逐个比对
五 获取目标节点的子节点,显示

代码如下,界面部分是一个listWidget和几个按键

`
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 
#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QDomDocument doc;

    //添加处理指令即XML说明
    QDomProcessingInstruction instruction;
    instruction = doc.createProcessingInstruction("xml",
                                                  "version= \"1.0\""
                                                  " encoding= \"UTF-8\"");
    doc.appendChild(instruction);

    //添加根元素
    QDomElement root = doc.createElement("书库");
    doc.appendChild(root);

    //添加第一个图书元素及其子元素
    QDomElement book = doc.createElement("图书");
    QDomAttr id = doc.createAttribute("编号");
    id.setValue(QString("1"));
    book.setAttributeNode(id);

    QDomElement title = doc.createElement("书名");
    QDomText text = doc.createTextNode("Qt");
    title.appendChild(text);

    QDomElement author = doc.createElement("作者");
    text = doc.createTextNode("shiming");
    author.appendChild(text);

    book.appendChild(title);
    book.appendChild(author);

    root.appendChild(book);

    //添加第二个图书元素及其子元素
    book = doc.createElement("图书");
    id = doc.createAttribute("编号");
    title = doc.createElement("书名");
    author = doc.createElement("作者");

    id.setValue(QString("2"));
    book.setAttributeNode(id);
    text = doc.createTextNode("Qt2");
    title.appendChild(text);
    text = doc.createTextNode("shiming");
    author.appendChild(text);
    book.appendChild(title);
    book.appendChild(author);
    root.appendChild(book);

    saveMyXml(doc);
}

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

void MainWindow::on_pushButton_5_clicked()
{
    //先清空显示
    ui->listWidget->clear();

    QDomDocument doc;
    openMyXmlReadOnly(doc);

    QDomNode docNode = doc.documentElement().firstChild();
    while (!docNode.isNull()) {
        if (docNode.isElement()){
            QDomElement elem = docNode.toElement();
            ui->listWidget->addItem(elem.tagName() + elem.attribute("编号"));
            QDomNodeList list = elem.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());
                }
            }
        }
        docNode = docNode.nextSibling();
    }
}

void MainWindow::on_pushButton_4_clicked()
{
    //先清空显示,然后显示“无法添加”,这样如果添加失败则显示“无法添加”
    ui->listWidget->clear();
    ui->listWidget->addItem("无法添加!");

    QDomDocument doc;
    openMyXmlReadOnly(doc);

    QDomElement root = doc.documentElement();    
    QString lastNum = root.lastChild().toElement().attribute("编号");

    QDomElement book = doc.createElement("图书");
    QDomAttr id = doc.createAttribute("编号");
    id.setValue(QString::number(lastNum.toInt() +1));
    book.setAttributeNode(id);

    QDomElement title = doc.createElement("书名");
    QDomText text = doc.createTextNode(ui->lineEditBookName->text());
    title.appendChild(text);
    book.appendChild(title);

    QDomElement author = doc.createElement("作者");
    text = doc.createTextNode(ui->lineEditAuthor->text());
    author.appendChild(text);
    book.appendChild(author);

    root.appendChild(book);

    saveMyXml(doc);
    //最后更改显示为“添加成功”
    ui->listWidget->clear();
    ui->listWidget->addItem("添加成功!");

}

void MainWindow::doXml(const QString operate)
{
    ui->listWidget->clear();
    ui->listWidget->addItem("没有找到相关内容");

    QDomDocument doc;
    openMyXmlReadOnly(doc);

    //以标签名查找
    QDomNodeList list = doc.elementsByTagName("图书");
    for (int i=0; ilineEditBookNum->text()){
            if (operate == "delete"){
                QDomElement root = doc.documentElement();
                root.removeChild(list.at(i));

                saveMyXml(doc);
                ui->listWidget->clear();
                ui->listWidget->addItem("删除成功");
            }else if (operate == "update") {
                QDomNodeList child = list.at(i).childNodes();
                child.at(0).toElement().firstChild()
                        .setNodeValue(ui->lineEditBookName->text());
                child.at(1).toElement().firstChild()
                        .setNodeValue(ui->lineEditAuthor->text());

                saveMyXml(doc);
                ui->listWidget->clear();
                ui->listWidget->addItem("更新成功");
            }else if (operate == "find") {
                ui->listWidget->clear();
                ui->listWidget->addItem(element.tagName()
                                        + element.attribute("编号"));
                QDomNodeList list = element.childNodes();
                for (int i=0; ilistWidget->addItem("  "
                                                + node.toElement().tagName()
                                                +":"
                                                + node.toElement().text());
                    }
                }
            }
        }
    }
}

void MainWindow::openMyXmlReadOnly(QDomDocument & doc)
{
    QFile file("my.xml");
    if (!file.open(QIODevice::ReadOnly))
        return;
    if (!doc.setContent(&file)){
        file.close();
        return;
    }
    file.close();
}

void MainWindow::openMyXmlWriteOnly(QDomDocument & doc)
{
    QFile file("my.xml");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return;
    if (!doc.setContent(&file)){
        file.close();
        return;
    }
    file.close();
}

void MainWindow::saveMyXml(QDomDocument & doc)
{
    QFile file("my.xml");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return;
    QTextStream out(&file);
    //将文档保存到文件,4为子元素缩进字符数
    doc.save(out, 4);
    file.close();
}

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

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

void MainWindow::on_pushButton_3_clicked()
{
    doXml("update");
}
`

你可能感兴趣的:(qt,qt5)