4、Qt使用TinyXML读写XML文件

一、下载TinyXML

访问下面的链接,点击“Download”下载 TinyXML文件

TinyXML download | SourceForge.net

二、使用TinyXML

创建一个Qt项目,名为MyTinyXML,基类选择“QMainWindow”,在项目文件夹中新建一个“TinyXML”文件夹,从下载好的 TinyXML文件拷贝如下文件到“TinyXML”文件夹中

右击项目名称,选择“添加现有文件”,把刚才拷贝的几个文件添加到项目中

mainwindow.h中包含头文件,并声明一个函数:

#include "./TinyXML/tinyxml.h"

void xmlInit();

更改mainwindow.cpp代码如下

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

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

    xmlInit();
}

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

void MainWindow::xmlInit()
{
    //文档类
    TiXmlDocument* xmlDocument = new TiXmlDocument();
    QString str = "test.xml";
    if(xmlDocument->LoadFile(str.toStdString().c_str())) //test.xml文件存在
    {
        delete xmlDocument;
        return;
    }

    //声明类
    TiXmlDeclaration* xmlDeclaration = new TiXmlDeclaration("1.0","UTF-8","");
    xmlDocument->LinkEndChild(xmlDeclaration);

    //注释类
    TiXmlComment* xmlComment = new TiXmlComment();
    xmlComment->SetValue("Person TinyXML" );
    xmlDocument->LinkEndChild(xmlComment);

    //元素类
    TiXmlElement* xmlElement = new TiXmlElement("Person");
    xmlElement->SetAttribute("index", 0);
    xmlDocument->LinkEndChild(xmlElement);

    //文本类
    TiXmlText* xmlText = new TiXmlText("name");
    xmlElement->LinkEndChild(xmlText);

    //保存
    xmlDocument->SaveFile("test.xml");

    delete xmlDocument;
}

运行程序,项目的构建目录下生成test.xml文件,文件内容如下:

  • 第一行是声明;
  • 第二行是注释;
  • 第三行是元素类,index是属性,0是属性的值,name是文本。

三、增加

 在mainwindow.h中声明一个函数:

void addElement();

 在mainwindow.cpp中定义函数内容如下:

void MainWindow::addElement()
{
    TiXmlDocument* xmlDocument = new TiXmlDocument();
    if(!xmlDocument->LoadFile("test.xml")) //没有test.xml文件
    {
        qDebug() << xmlDocument->ErrorDesc();

        xmlInit(); //创建test.xml
    }

    //获取根节点
//    TiXmlElement* rootElement = xmlDocument->RootElement();
//    const char* elemValue = rootElement->Value();
//    if(strcmp(elemValue, "Person") != 0) //节点不存在
//    {
//        qDebug() << xmlDocument->ErrorDesc();
//        delete xmlDocument;
//        return;
//    }

    //与上面注释中的代码作用一样,都是查找根节点"Person"
    //查找xml文件中第一个名为Person的节点
    TiXmlElement* rootElement = xmlDocument->FirstChildElement("Person");
    if(rootElement == nullptr) //节点不存在
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return;
    }

    if(rootElement)
    {
        //创建一个节点
        TiXmlElement* xmlElement = new TiXmlElement("Teacher");
        rootElement->LinkEndChild(xmlElement); //链接到根节点下

        //添加两个属性
        xmlElement->SetAttribute("index", 0);
        xmlElement->SetAttribute("type", "教师");

        //创建一个显示姓名的节点
        TiXmlElement* childElement = new TiXmlElement("name");
        xmlElement->LinkEndChild(childElement);
        TiXmlText* xmlText = new TiXmlText("王老师");
        childElement->LinkEndChild(xmlText);

        //创建一个显示年纪的节点
        childElement = new TiXmlElement("age");
        xmlElement->LinkEndChild(childElement);
        xmlText = new TiXmlText("22");
        childElement->LinkEndChild(xmlText);
    }

    xmlDocument->SaveFile();
    delete xmlDocument;
}

在构造函数中调用addElement()函数,运行程序,test.xml中增加了有关王老师的信息:

四、遍历

在mainwindow.h中声明一个函数:

void ergodicElement();

在mainwindow.cpp中定义函数内容如下:

 

void MainWindow::ergodicElement()
{
    TiXmlDocument* xmlDocument = new TiXmlDocument();
    if(!xmlDocument->LoadFile("test.xml")) //没有test.xml文件
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return;
    }

    //查找xml文件中第一个名为Person的节点
    TiXmlElement* rootElement = xmlDocument->FirstChildElement("Person");
    if(rootElement == nullptr) //节点不存在
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return;
    }

    if(rootElement)
    {
        //"Teacher"节点
        for(TiXmlElement* childElement = rootElement->FirstChildElement("Teacher");
                 childElement != nullptr; childElement = childElement->NextSiblingElement("Teacher"))
        {
            //获取属性信息
            int index = 0;
            QString type;

            //读取int属性用element->QueryIntAttribute("属性名称", &value);
            //读取double属性用element->QueryDoubleAttribute("属性名称", &value);
            //读取字符串属性用value = element->Attribute("属性名称");
            //childElement->QueryIntAttribute("index", &index);
            index = QString(childElement->Attribute("index")).toInt(); //也可以从QString转成int
            type = childElement->Attribute("type");

            qDebug() << "index: " << index;
            qDebug() << "type: " << type;

            const char* elemValue;

            //遍历"Teacher"节点下的节点信息
            for(TiXmlElement* element = childElement->FirstChildElement();
                     element != nullptr; element = element->NextSiblingElement())
            {
                elemValue = element->Value(); //获取节点名称
                if(strcmp(elemValue, "name") == 0)
                {
                    //读文本信息
                    QString name = element->FirstChild()->ToText()->Value();
                    qDebug() << "name: " << name;
                }
                else if(strcmp(elemValue, "age") == 0)
                {
                    //读文本信息
                    QString age = element->FirstChild()->ToText()->Value();
                    qDebug() << "age: " << age;
                }
            }
        }
    }

    delete xmlDocument;
}

 在构造函数中调用ergodicElement()函数,运行程序,应用程序输出窗口输出如下信息,与test.xml中的信息一致:

五、修改

在mainwindow.h中声明一个函数:

void changeElement();

在mainwindow.cpp中定义函数内容如下:

void MainWindow::changeElement()
{
    TiXmlDocument* xmlDocument = new TiXmlDocument();
    if(!xmlDocument->LoadFile("test.xml")) //没有test.xml文件
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return;
    }

    //查找xml文件中第一个名为Person的节点
    TiXmlElement* rootElement = xmlDocument->FirstChildElement("Person");
    if(rootElement == nullptr) //节点不存在
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return;
    }

    if(rootElement)
    {
        //"Teacher"节点
        for(TiXmlElement* childElement = rootElement->FirstChildElement("Teacher");
                 childElement != nullptr; childElement = childElement->NextSiblingElement("Teacher"))
        {
            //更改属性信息
            childElement->SetAttribute("index", 1);
            childElement->SetAttribute("type", "学生");

            const char* elemValue;

            //遍历"Teacher"节点下的节点信息
            for(TiXmlElement* element = childElement->FirstChildElement();
                     element != nullptr; element = element->NextSiblingElement())
            {
                elemValue = element->Value(); //获取节点名称
                if(strcmp(elemValue, "name") == 0)
                {
                    //修改文本信息
                    element->FirstChild()->SetValue("宋同学");
                }
                else if(strcmp(elemValue, "age") == 0)
                {
                    element->FirstChild()->SetValue("18");
                }
            }
        }
    }

    xmlDocument->SaveFile();
    delete xmlDocument;
}

在构造函数中调用changeElement()函数,运行程序,test.xml中的内容被更改如下:

六、删除

在mainwindow.h中声明一个函数:

void deleteElement();

在mainwindow.cpp中定义函数内容如下:

void MainWindow::deleteElement()
{
    TiXmlDocument* xmlDocument = new TiXmlDocument();
    if(!xmlDocument->LoadFile("test.xml")) //没有test.xml文件
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return;
    }

    //查找xml文件中第一个名为Person的节点
    TiXmlElement* rootElement = xmlDocument->FirstChildElement("Person");
    if(rootElement == nullptr) //节点不存在
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return;
    }

    if(rootElement)
    {
        //"Teacher"节点
        for(TiXmlElement* childElement = rootElement->FirstChildElement("Teacher");
                 childElement != nullptr; childElement = childElement->NextSiblingElement("Teacher"))
        {
            //删除index属性信息
            childElement->RemoveAttribute("index");

            const char* elemValue;
            //遍历"Teacher"节点下的节点信息
            for(TiXmlElement* element = childElement->FirstChildElement();
                     element != nullptr; element = element->NextSiblingElement())
            {
                elemValue = element->Value(); //获取节点名称
                if(strcmp(elemValue, "age") == 0)
                {
                    //删除age节点
                    childElement->RemoveChild(element);
                }
            }
        }
    }

    xmlDocument->SaveFile();
    delete xmlDocument;
}

在构造函数中调用deleteElement()函数,运行程序,test.xml中属性index和节点age被删除:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值