Qt 中的XML

news2024/12/21 10:57:31

XML的基本介绍:

在前端开发中:HTML是用来显示数据,而XML是用来传输和存储数据的

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 标签没有被预定义。您需要自行定义标签
  • XML 被设计为具有自我描述性
  • XML 是 W3C 的推荐标准

XML 应用于 web 开发的许多方面,常用于简化数据的存储和共享。

  • 通过 XML,可以在不兼容的系统之间轻松地交换数据。
  • XML 独立于硬件、软件以及应用程序,XML 使您的数据更可用,也更有用。
  • XML 数据以文本格式存储。这使得 XML 在不损失数据的情况下,更容易扩展或升级到新的操作系统、新应用程序或新的浏览器

 在Qt中的XML:

使用Qt XML模块来对XML文档进行处理

  1. 使用DOM方法对XML文档进行读/写
  2. SAX方法对XML进行存取(这种方法已经过时)
  3. 从Qt5开始,使用Qt Core中的QXmlStreamReaderQXmlStreamWriter,使用流的方式对XML文档进行读写。

XML文件的介绍:

<? xml version="1.0" encoding="UTF-8"?>//XML说明,version版本号,encoding版本号
<root>//根元素
   <id id="1">//元素 元素属性
       <name>王老五</name>//元素 内容
   </id>
   <id id="2">
       <name>张老四</name>
   </id>
</root>//结束

xml的一些内容: 

  1. 基本格式:<xxx>内容</xxx>
  2. XML有且仅有一个根元素      root 
  3. 元素: root  id   name
  4. 属性格式: <元素 元素=”属性“>
  5. 内容:<元素>text</元素>

DOM中XML的表示:

XML说明QDomProcessingInstruction
XML元素QDomElement
XML 属性QDomAttr
XML 内容QDomText
全部同一使用QDomNode

QDomNode 

isProcessingInstruction()判断是否为xml说明
isElement()判断是否为xml元素
isAttr()判断是否为xml属性
isText()判断是否为xml内容
toProcessingInstruction()转化为xml说明
toElement()转化为xml元素
toAttr()转化为xml属性
toText()转化为xml内容

QDomDocument(Dom文档类)

使用QDomDocument表示整个XML文档,提供对文档数据的主要访问。

使用时需要在pro文件中添加:

QT += xml

常用的函数:

toString(int indent=1)将分析的文档转换为文本的形式表示,1为缩进
toByteArray(int indent=1)将分析的文档转换回其文本表示形式,1为缩进
setContent()此函数从字节数组数据分析 XML 文档,并将其设置为文档的内容。它尝试按照 XML 规范的要求检测文档的编码。
importNode()节点导入节点从另一个文档导入到此文档。importedNode 保留在原始文档中;此函数创建可在此文档中使用的副本。
elementsByTagName()返回一个QDomNodeList,其中包含文档中具有名称标记名的所有元素。节点列表的顺序是它们在元素树的预序遍历中遇到的顺序。
elementById(QString id)返回根id匹配的元素
documentElement()返回文档的根元素
doctype()返回此文档的文档类型
createTextNode()为可以插入到文档树中的字符串创建一个文本节点
createProcessingInstruction()创建一个可以插入到文档中的新处理指令
createEntityReference(name)创建一个名为 name 的新实体引用,可以插入到文档中
createElementNS()创建一个具有命名空间支持的新元素,该元素可以插入到 DOM 树中。
createElemrnt(tagname)创建一个名为 tagName 的新元素,可以插入到 DOM 树中
createComment()为可以插入到文档中的字符串创建一个新注释
createAttributeNS()创建具有命名空间支持的新属性,该属性可以插入到元素中。
createAttribute(name)创建一个名为 name 的新属性,该属性可以插入到元素中

使用QDomDocument 读取xml中的数据:

  1. 创建一个QDomDocument对象
  2. 使用QFIle 打开xml文档
  3. 使用QDomDocument::setContent(file)把文件中的内容导入QDomDocument
  4. 使用QDocNode获取内容

首先创建一个xml文件,后缀为 .xml,然后把该文件添加到项目的资源文件中:

 xml文件中添加以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <id id="1">
       <name>wanglaowu</name>
   </id>
   <id id="2">
       <name>zhanglaosi</name>
   </id>
</root>

在main函数中添加以下代码:

#include <QApplication>
#include<QDomDocument>
#include<QMessageBox>
#include<QFile>
#include<QDebug>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);


    QDomDocument domdoc("myDom");//创建一个Dom文档对象
    QFile file(":/new/prefix1/XMLtext.xml");
    if(!file.open(QFile::ReadOnly))
    {
        QMessageBox::information(0,"提示信息","xml文件打开失败",QMessageBox::Ok);
        return 0;
    }
    if(!domdoc.setContent(&file))//读取文件内容到domdoc
    {
        file.close();
        return 0;
    }
    file.close();//读取完关闭文件
    QDomNode firstNode=domdoc.firstChild();//获取第一个元素,XML说明
    qDebug()<<qPrintable(firstNode.nodeName())//输出版本号
           <<qPrintable(firstNode.nodeValue());//输出编码类型


    return a.exec();
}

对于qPrintable的解释:

const char *qPrintable(const QString &str)

相当于:将 str 作为 .这相当于 str.toLocal8Bit().constData()

 输出xml中的全部内容:

 可以把XML看作一棵树:

    QDomElement docElem=domdoc.documentElement();//获取根元素
    QDomNode n=docElem.firstChild();//获取第一个子节点
    while(!n.isNull())//不为空的话
    {
        if(n.isElement())//如果是元素的话
        {
            QDomElement e=n.toElement();//获取该元素

            qDebug()<<qPrintable(e.tagName())//获取元素标记
                   <<qPrintable(e.attribute("id"));//id属性的值

            QDomNodeList list=e.childNodes();//获取e的全部子节点

            for(int i=0;i<list.count();i++)//遍历列表
            {
                QDomNode node=list.at(i);
                if(node.isElement())
                {
                    qDebug()<<"   "<<qPrintable(node.toElement().tagName())//输出元素名
                           <<qPrintable(node.toElement().text());//输出内容
                }
            }
        }
        n=n.nextSibling();//转到下一个兄弟节点

    }

 创建一个XML文件并添加内容:

构建思路:

 代码:

    QDomDocument doc;//创建一个Dom对象
    QDomProcessingInstruction instruction;//XML说明
    instruction=doc.createProcessingInstruction
            ("xml","version=\"1.0\" encoding=\"UTF-8\"");//创建XML说明
    doc.appendChild(instruction);//添加XML说明

    //创建根元素
    QDomElement root=doc.createElement("学生信息");
    doc.appendChild(root);//添加根元素
    //创建学生信息
    QDomElement id=doc.createElement("学号");
    QDomAttr number=doc.createAttribute("学号");//属性
    QDomElement name=doc.createElement("姓名");
    QDomElement age=doc.createElement("年龄");
    QDomElement height=doc.createElement("身高");
    QDomElement weight=doc.createElement("体重");
    QDomText text;//内容

    number.setValue(QString("1"));//设置学号的值
    id.setAttributeNode(number);//id元素中添加number属性

    //添加学生信息
    text=doc.createTextNode("王一");
    name.appendChild(text);
    text=doc.createTextNode("15");
    age.appendChild(text);
    text=doc.createTextNode("160");
    height.appendChild(text);
    text=doc.createTextNode("40");
    weight.appendChild(text);

    //把这些信息添加到id元素中
    id.appendChild(name);
    id.appendChild(age);
    id.appendChild(height);
    id.appendChild(weight);

    //将id添加到根元素中
    root.appendChild(id);

    //第二个学生
    id=doc.createElement("学号");
    number=doc.createAttribute("学号");//属性
    name=doc.createElement("姓名");
    age=doc.createElement("年龄");
    height=doc.createElement("身高");
    weight=doc.createElement("体重");

    number.setValue(QString("2"));//设置学号
    id.setAttributeNode(number);//id元素中设置number属性

    //添加信息
    text=doc.createTextNode("张三");
    name.appendChild(text);
    text=doc.createTextNode("16");
    age.appendChild(text);
    text=doc.createTextNode("165");
    height.appendChild(text);
    text=doc.createTextNode("45");
    weight.appendChild(text);

    //把这些信息添加到学号中
    id.appendChild(name);
    id.appendChild(age);
    id.appendChild(height);
    id.appendChild(weight);

    //将id添加到根元素中
    root.appendChild(id);

    QFile file("my.xml");
    if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))return;
    QTextStream out(&file);
    doc.save(out,4);//保存到out中,4格缩进
    file.close();

打开该文件:

查找、修改、删除操作:

 

void Widget::find_updata_delete(const QString S)//
{
    QFile file("my.xml");//打开该文件
    if(!file.open(QFile::ReadOnly))
    {
        return;//打开失败的话退出
    }
    QDomDocument doc;
    if(!doc.setContent(&file))//获取数据失败
    {
        file.close();
        return;
    }
    //获取成功的话
    QDomNodeList list=doc.elementsByTagName("学号");//获取标签
    for(int i=0;i<list.count();i++)//遍历这些标签
    {
        QDomElement e=list.at(i).toElement();//获取元素
        if(e.attribute("学号")==ui->lineEdit->text())//如果匹配成功的话
        {
            if(S=="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();//关闭文件
            }
            else if(S=="updata")
            {
                QDomNodeList child=list.at(i).childNodes();//获取当前节点所有的子节点
                child.at(0).toElement().firstChild().setNodeValue(ui->lineEdit_2->text());//更新姓名
                child.at(1).toElement().firstChild().setNodeValue(ui->lineEdit_3->text());//更新年龄
                child.at(2).toElement().firstChild().setNodeValue(ui->lineEdit_4->text());//更新身高
                child.at(3).toElement().firstChild().setNodeValue(ui->lineEdit_5->text());//更新体重
                QFile file("my.xml");
                if(file.open(QIODevice::WriteOnly|QIODevice::Truncate))
                    return;
                QTextStream out(&file);
                doc.save(out,4);//保存到文件中
                file.close();//关闭文件
            }
            else if(S=="find")
            {
                qDebug()<<e.tagName()<<" "<<e.attribute("学号");//输出元素名和学号
                QDomNodeList nodeList=e.childNodes();//获取内容节点
                for(int i=0;i<nodeList.count();i++)
                {
                    QDomNode node=nodeList.at(i);
                    if(node.isElement())
                    {
                        qDebug()<<node.toElement().tagName()<<" "<<node.toElement().text();//输出元素名和内容
                    }
                }
            }

        }

    }
}
void Widget::on_pushButton_clicked()//查找
{
    find_updata_delete("find");
}

 运行结果:

以上是Dom简单使用xml的方法。(感觉有点繁琐)

XML流

从Qt 4.3开始引入两个新类来读取和写入XML文档:

QXmlStreamReader类:

  • 是一个快速的解析器,使用简单的流API来读取格式良好的XML文档
  • QXmlStreamReader可以从QIODevice或QByteArray中读取数据
  • 流读取器:将XML文档报告为一个记号流,使用程序代码自身来驱动循环,在需要的时候可以从读取器中一个接着一个地拉出记号,使用readNext()函数获取记号

 QXmlStreamReader::TokenType:

常量描述
QXmlStreamReader::NoToken没有读过任何东西。
QXmlStreamReader::Invalid使用error()和errorString()中报告错误
QXmlStreamReader::StartDocument在documentVersion()中报告XML版本号,使用documentEncoding()中指定文档的编码
QXmlStreamReader::EndDocument报告文档结束
QXmlStreamReader::StartElement使用namespaceUri()和name()来报告元素开始,可以使用attributes()来获取属性
QXmlStreamReader::EndElement使用nameSpaceUri()和name()来报告元素结束
QXmlStreamReader::Characters使用text()来报告字符,如果字符是空白,那么isWhitespace()返回true,如果字符源于CDATA部分,那么isCDATA()返回true
QXmlStreamReader::Comment使用在text()中报告注释
QXmlStreamReader::DTD使用在 text() 中报告 DTD,在 notationDeclDeclarations() 中报告表示法声明,在 entityDeclarations() 中报告实体声明。DTD 声明的详细信息在 dtdName()、dtdPublicid和dtdSystemid() 中报告
QXmlStreamReader::EntityReference报告无法解析的实体引用。引用的名称在 name() 中报告,替换文本在 text() 中报告。
QXmlStreamReader::ProcessingInstruction使用processingInstruction Target()和processingInstruction Data()中报告处理指令

使用QXmlStreamReader读取xml文档:

具体流程:

  1. 先打开文件  file
  2. 创建一个阅读器,使用setDevice()设置读取对象
  3. 使用readNext()读取一个记号
  4. 使用读取的记号进行判断
#include <QApplication>
#include<QXmlStreamReader>
#include<QFile>
#include<QDebug>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QFile file(":/new/xml/my.xml");
    if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
    {
       return 0;
    }
    QXmlStreamReader reader;//创建一个阅读器
    reader.setDevice(&file);//设置需要读取的文件
    while(!reader.atEnd())//如果不到结尾
    {
        QXmlStreamReader::TokenType type=reader.readNext();//获取一个记号
        if(type==QXmlStreamReader::StartDocument)//读取XML说明
        {
            qDebug()<<reader.documentVersion()<<"  "<<reader.documentEncoding();//读取版本号和编码类型
        }
        if(type==QXmlStreamReader::StartElement)//获取元素
        {
            qDebug()<<reader.name();//获取元素名
            if(reader.attributes().hasAttribute("id"))//如果有属性
            {
                qDebug()<<reader.attributes().value("id");//输出属性
            }
        }
        if(type==QXmlStreamReader::EndElement)//获取结束元素
        {
            qDebug()<<reader.name();
        }
        if(type==QXmlStreamReader::Characters&&!reader.isWhitespace())
        {
            qDebug()<<reader.text();//读取内容
        }
    }
    if(reader.hasError())
    {
        qDebug()<<"error:"<<reader.errorString();
    }
    file.close();//关闭文件

    return a.exec();
}

 QXMLStreamWriter

用于编写XML文档

常用函数:

setAutoFormatting()设置自动化类型
hasError()写入失败返回true
setCodec()设置解码器,默认使用UTF-8
setDevice()设置写入的设备
writeTextElement()写入带有内容的元素
writeStartElement()写入起始元素
writeStartDocument()写入XML版本号和编码信息
writeProcessingInstruction()编写包含目标和数据 XML 处理指令
writeNamespace()为带有前缀命名空间 Uri 编写命名空间声明
writeEndElement()关闭上一个开始元素
writeEndDocument()关闭所有剩余的打开开始元素并写入换行符
writeEmptyElement()写入一个带有名称的空元素
writeDTD()写入 DTD 节
writeAttributes()写入属性

例子: 

    QFile file("Myxml.xml");
    if(!file.open(QIODevice::WriteOnly|QIODevice::Text))
    {
        return 0;
    }
    QXmlStreamWriter Writer;
    Writer.setDevice(&file);//获取流
    Writer.setAutoFormatting(true);
    Writer.writeStartDocument();//添加XML说明(版本号和编码信息
    Writer.writeStartElement("student");//写入起始元素
    Writer.writeStartElement("id");
    Writer.writeAttribute("id","1");//写入属性
    Writer.writeTextElement("name","王维");
    Writer.writeTextElement("age","15");
    Writer.writeTextElement("height","165");
    Writer.writeTextElement("weight","50");
    Writer.writeEndElement();//结束id元素编辑
    Writer.writeEndElement();//结束student元素编辑
    Writer.writeEndDocument();//结束整个的编辑
    file.close();//关闭文件

 

参考文档: 

XML 的用途 (w3school.com.cn)

XML Processing | Qt XML 5.15.12

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/371305.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超简单的待办事项列表管理器todo

什么是 todo ? todo 是一个自托管的 todo web 应用程序&#xff0c;可让您以简单且最少的方式跟踪您的 todo。&#x1f4dd; 老苏觉得和之前介绍的 KissLists 比较像 文章传送门&#xff1a;最简单的共享列表服务器KissLists 官方提供了 Demo 演示站点&#xff1a;https://tod…

零基础的人如何入门 Python ?看完这篇文章你就懂了

第一部分&#xff1a;编程环境准备 零基础入门Python的话我不建议用IDE&#xff0c;IDE叫集成开发环境&#xff0c;这东西一般是专业程序员用来实战开发用的&#xff0c;好处很多&#xff0c;比如&#xff1a;调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测…

Android-MVVM之快速上手ViewModel

Android-MVVM之快速上手ViewModel什么是ViewModel&#xff1f;ViewModel生命周期&#xff1f;ViewModel的使用&#xff1f;什么是ViewModel&#xff1f; 简单来说&#xff0c;就是让view层(视图层)与model层(数据层)分离开来的桥梁。让view层展示ui&#xff0c;不持有数据。 Vi…

【2021春节】解题领红包之番外篇

【2021春节】解题领红包之番外篇前言原始代码解题思路flag1寻找flag2的寻找前言 记录下jsfuck的另类&#xff0c;时间都过去两年了&#xff0c;确实有点久远。。。 原始代码 要求找出flag1和flag2值 ([][])[([][[]][])[!![]](!![][][(![][])[[]](![][])[!![]!![]](![][])[!![…

Vue基础入门讲义(二)-语法基础

文章目录1.vue入门案例1.1.HTML模板1.2.vue渲染1.3.双向绑定1.4.事件处理2.Vue实例2.1.创建Vue实例2.2.模板或元素2.3.数据2.4.方法3.生命周期钩子3.1.生命周期3.2.钩子函数3.3.this1.vue入门案例 1.1.HTML模板 在项目目录新建一个HTML文件 01-demo.html 1.2.vue渲染 01-d…

SSM框架-AOP概述、Spring事务

16 spring整合mybatis 16.1 前情代码 实体类 public class Account {private Integer id;private String name;private Double money;public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getName() {return name;}public void …

搭建k8s高可用集群—20230225

文章目录多master&#xff08;高可用&#xff09;介绍高可用集群使用技术介绍搭建高可用k8s集群步骤1. 准备环境-系统初始化2. 在所有master节点上部署keepalived3.1 安装相关包3.2 配置master节点3.3 部署haproxy错误解决3. 所有节点安装Docker/kubeadm/kubelet4. 部署Kuberne…

对redis之键值型数据库的理解

键值数据库&#xff0c;首先就要考虑里面可以存什么样的数据&#xff0c;对数据可以做什么样的操作&#xff0c;也就是数据模型和操作接口。它们看似简单&#xff0c;实际上却是我们理解 Redis 经常被用于缓存、秒杀、分布式锁等场景的重要基础。理解了数据模型&#xff0c;你就…

2022年网络安全竞赛——数字取证调查attack.pcapng

攻击日志分析:需求环境可私信博主获取 任务环境说明: 服务器场景:PYsystem0031服务器场景操作系统:未知服务器场景FTP用户名:anonymous 密码:空从靶机服务器的FTP上下载attack.pcapng数据包文件,通过分析数据包attack.pcapng,找出黑客的IP地址,并将黑客的IP地址作为FL…

SPI协议介绍

SPI协议介绍 文章目录SPI协议介绍一、 SPI硬件知识1.1 硬件连线1.2 SPI控制器内部结构二、 SPI协议2.1 传输示例2.2 SPI模式致谢一、 SPI硬件知识 1.1 硬件连线 引脚含义如下&#xff1a; 引脚含义DO(MOSI)Master Output, Slave Input&#xff0c;SPI主控用来发出数据&#x…

逆向之Windows PE结构

写在前面 对于Windows PE文件结构&#xff0c;个人认为还是非常有必要掌握和了解的&#xff0c;不管是在做逆向分析、免杀、病毒分析&#xff0c;脱壳加壳都是有着非常重要的技能。但是PE文件的学习又是一个非常枯燥过程&#xff0c;希望本文可以帮你有一个了解。 PE文件结构…

buu [NCTF2019]babyRSA 1

题目描述&#xff1a; 题目分析&#xff1a; 首先明确两个公式&#xff1a; e*d 1 mod (p-1)(q-1) ed1 e*d - 1 k(p-1)(q-1)想要解出此题&#xff0c;我们必须知道n,而要知道n,我们要知道p和q的值通过 e*d 的计算&#xff0c;我们知道其长度为2066位&#xff0c;而生成p的…

《分布式技术原理与算法解析》学习笔记Day22

哈希与一致性哈希 在分布式系统中&#xff0c;哈希和一致性哈希是数据索引或者数据分布的常见实现方式。 数据分布设计原则 在分布式数据存储系统中&#xff0c;做存储方案选型时&#xff0c;一般会考虑以下因素&#xff1a; 数据均匀数据稳定节点异构性隔离故障域性能稳定…

Delphi Http Https 最好的解决方法(三) LoadLibrary扩展

开发环境: Delphi XE 10.1 Berlin 前提文章: Delphi Http Https 最好的解决方法(二) 目录 1. 项目描述 2. 问题描述 3. 解决方案 3.1 主程序在导入dll方法单元处理(不推荐) 3.2 在dll的工程文件处加入(不推荐) 3.3 在dll的工程文件获取dll(HelpTool.dll)的当前路径(推荐方…

gitlab 安装到项目上传一篇解决

文章目录1.安装1.1创建挂载目录1.2启动1.3 配置gitlab查看docker admin 账户初始密码注册普通用户2.1进入注册2.2创建后通过登录admin审批3.2 步骤13.2 步骤23.3步骤33.4 项目添加成员4 使用成员用户,上传到新建的项目中4.1 复制项目地址4.2使用 git here 克隆项目4.3进入下载目…

读懂分布式事务

一、概述 1.1 什么是分布式事务 事务我们都很熟悉&#xff0c;事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元&#xff0c;组成这组操作的各个单元&#xff0c;要么全部成功&#xff0c;要么全部失败。 事务有四大特性&#xff1a; Atomic&#xf…

rabbitmq安装和thinkphp6简单操作思路

1、安装rabbitmq 2、crontab定时检测rabbtimq状态 2、使用thinphp6.0框架rabbitmq示例,supervisor守护消费者 3、RabbitMQ有四种交换机类型 rabbitmq组成部分如下&#xff1a; Broker&#xff1a;消息队列服务进程&#xff0c;此进程包括两个部分&#xff1a;Exchange和Que…

代码随想录算法训练营day42 |动态规划之背包问题 11.分割等和子集 1049. 最后一块石头的重量 II 494. 目标和

day4211.分割等和子集1.dp数组的含义2.确定递推公式3.dp数组初始化4.确定遍历顺序5.打印dp数组1049. 最后一块石头的重量 II1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组494. 目标和1.确定dp数组以及下标的含义2.确定递推公式3.…

Bootstrap系列之Flex布局

文章目录Bootstrap中的Flexd-flex与d-inline-flex也存在响应式变化flex水平布局flex垂直布局flex水平与垂直也存在响应式变化内容排列&#xff08;justify-content响应式变化也存在于这里sm&#xff0c;md&#xff0c;lg&#xff0c;xl&#xff09;子元素对齐方式Align items&a…

Oracle-00-卸载篇

这里给出企业级的Oracle 10g的卸教程,新安装的19c并没有正经去做卸载的操作,为了后面教程的进度,这里就先借用下10g,如果有需要会重新更新19c的卸载教程 windows服务中将Oracle所有服务全部停掉 选中Oracle - OraDb10g_home2->Oracle Installation Products->Univers…