qt5-按字节读取并解析含属性的xml文件

news2024/9/19 10:41:23

参考:
对XML文件读取和编辑2-QXmlStreamReader读取 - 知乎
https://zhuanlan.zhihu.com/p/358862429

本地环境:
win10专业版,64位,Qt 5.12

代码已测试通过。


问题描述

需要按字节读取一个文档,解析其中具有xml格式的部分,并存储到一个Hash表中,方便使用。xml标签上可能带有属性信息,如下图红线所示:
在这里插入图片描述

解决思路

按字节读取参考:
qt5-入门-QByteArray-CSDN博客
https://blog.csdn.net/pxy7896/article/details/137583591

提取后发现文字内容大概如下:

"<Notes><UUID>71bf0eb6-0477-41e8-8520-f1f5fafac932</UUID><Type>Synthetic</Type><ConfirmedExperimentally>0</ConfirmedExperimentally><CustomMapLabel>Y14837</CustomMapLabel><UseCustomMapLabel>1</UseCustomMapLabel><Description>Cloning vector pUC57, complete sequence.</Description><Created UTC=\"1:41:49\">2020.7.2</Created><LastModified UTC=\"1:8:0\">2021.10.8</LastModified><AccessionNumber>Y14837</AccessionNumber><SequenceClass>UNA</SequenceClass><TransformedInto>unspecified</TransformedInto><References><Reference authors=\"Markausakas A, Dreguniene G.\" journal=\"Unpublished\" title=\"A new cloning vector pUC57\"/><Reference authors=\"Markauskas A.\" journal=\"Submitted (16-SEP-1997) A. Markauskas, Fermentas AB, Graiciuno 8, Vilnius 2028, LITHUANIA\" title=\"Direct Submission\"/></References><Comments>&lt;a href='http://www.informaxinc.com/'>http://www.informaxinc.com/&lt;/a>&lt;br>ORIGDB|GenBank</Comments></Notes>" 

可以看到,<Reference>不仅携带属性信息,还可能重复,所以应该使用QMultiHash

总的设计思路是:当QXmlStreamReader::TokenTypeQXmlStreamReader::StartElement读取标签名称和属性信息,存储到合适的字典里;当是QXmlStreamReader::Characters时读取标签内容;当是QXmlStreamReader::EndElement时,存储到外层字典中,并清空临时值。这样一直读取到这部分结束。

实现

void process(QXmlStreamReader& xml, QMultiHash<QString, QHash<QString, QString>>& hash) {
	// 临时存储
    QString name, value;
    QHash<QString, QString> attrHash;
    while(!xml.atEnd()) {
        QXmlStreamReader::TokenType token = xml.readNext();
        switch ((int)token) {
            case QXmlStreamReader::NoToken:
            //qDebug()<<"没有读到任何东西";
            break;
        case QXmlStreamReader::Invalid:
            //qDebug()<<"发生错误,在error()和errorString()中报告.";
            break;
        case QXmlStreamReader::StartDocument:
            //qDebug()<<"读取文件开始-"<<"版本号:"<<xml.documentVersion()<<"编码格式:"<<xml.documentEncoding();
            break;
        case QXmlStreamReader::EndDocument:
            //qDebug()<<"读取文件结束";
            break;
        case QXmlStreamReader::StartElement:    //开始读取一个元素
        {

            // 如果是元素开始标签
            name = xml.name().toString();
            // 输出标签的属性
            QXmlStreamAttributes attributes = xml.attributes();
            // 此时有属性,需要填充字典
            if (!attributes.isEmpty()) {
                foreach (const QXmlStreamAttribute &attribute, attributes) {
                    attrHash.insert(attribute.name().toString(), attribute.value().toString());
                }
            }

        }
            break;
        case QXmlStreamReader::EndElement:  //读取一个元素结束
        {
            if(name == xml.name().toString()) {
                //attrHash.insert("name", name);
                attrHash.insert("value", value);
                hash.insert(name, attrHash);
            }
            // 清空
            name = "";
            value = "";
            attrHash.clear();
        }
            break;
        case QXmlStreamReader::Characters:  //读取元素中的文本信息
        {
            QString str = xml.text().toString();
            if(!xml.isWhitespace())
            {
                value = str;
            }
        }
            break;
        case QXmlStreamReader::Comment: //文本注释
            break;
        case QXmlStreamReader::ProcessingInstruction:
            //qDebug()<<"ProcessingInstruction: "<< xml.text();
            break;
        }
    } // 读取结束
}

使用:

QString blockContent = byteArray.mid(ptr, blockSize);
// 原始bytes中可能有\n,注意去掉。。。
QXmlStreamReader xml(blockContent);
QMultiHash<QString, QHash<QString, QString> > curHash;
process(xml, curHash);
// 打印一下结果
for (QMultiHash<QString, QHash<QString, QString>>::const_iterator it = curHash.constBegin(); it != curHash.constEnd(); ++it) {
	qDebug() << it.key() << it.value() << endl;
}

/* 解析结果
"Created" QHash(("value", "2020.7.2")("UTC", "1:41:49")) 

"LastModified" QHash(("value", "2021.10.8")("UTC", "1:8:0")) 

"Comments" QHash(("value", "<a href='http://www.informaxinc.com/'>http://www.informaxinc.com/</a><br>ORIGDB|GenBank")) 

"Type" QHash(("value", "Synthetic")) 

"Description" QHash(("value", "Cloning vector pUC57, complete sequence.")) 

"CustomMapLabel" QHash(("value", "Y14837")) 

"UseCustomMapLabel" QHash(("value", "1")) 

"ConfirmedExperimentally" QHash(("value", "0")) 

"SequenceClass" QHash(("value", "UNA")) 

"UUID" QHash(("value", "71bf0eb6-0477-41e8-8520-f1f5fafac932")) 

"TransformedInto" QHash(("value", "unspecified")) 

"Reference" QHash(("value", "")("journal", "Submitted (16-SEP-1997) A. Markauskas, Fermentas AB, Graiciuno 8, Vilnius 2028, LITHUANIA")("authors", "Markauskas A.")("title", "Direct Submission")) 

"Reference" QHash(("value", "")("journal", "Unpublished")("authors", "Markausakas A, Dreguniene G.")("title", "A new cloning vector pUC57")) 

"AccessionNumber" QHash(("value", "Y14837")) 
*/

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

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

相关文章

【C语言回顾】数组

前言1. 数组2. 一维数组2.1 一维数组的创建2.2 一维数组的初始化2.3 一维数组的使用2.3.1 一维数组的下标2.3.2 一维数组的输入和输出 2.4 一维数组在内存中的存储 3. 二维数组3.1 二维数组的创建3.2 二维数组的初始化3.3 二维数组的使用3.3.1 二维数组的下标3.3.2 二维数组的输…

ELK日志收集和备份填坑实战 (滞后8个小时等时区问题)

ES的备份&#xff1a;ES快照备份 根据时间&#xff0c;每天零点在Linux机器crontab来调用api接口实现快照备份&#xff0c;通过快照备份&#xff0c;可以定准恢复到某一天的日志。 现象&#xff1a;&#xff08;坑&#xff1a;但是恢复某一天日志&#xff0c;发现会少8小时的日…

暴力破解密码自动阻断

1 re模块 re 模块是 Python 中用于正则表达式操作的模块。正则表达式&#xff08;Regular Expression&#xff09;是一种强大的文本处理工具&#xff0c;它使用一种特殊的字符序列来表示字符串中的模式&#xff0c;并可以通过模式匹配、查找、替换等操作对文本进行高效处理。 …

【Qt】:对话框(二)

对话框 一.消息对话框&#xff08;QMessageBox&#xff09;1.自己构建2.使用静态函数构建 二.颜色对话框&#xff08;QDialog&#xff09;三.文件对话框&#xff08;QFileDialog&#xff09;四.字体对话框&#xff08;QFontDialog&#xff09;五.输入对话框&#xff08;QInputD…

光场相机建模与畸变校正改进方法

摘要&#xff1a;光场相机作为一种新型的成像系统&#xff0c;可以直接从一次曝光的图像中得到三维信息。为了能够更充分有效地利用光场数据包含的角度和位置信息&#xff0c;完成更加精准的场景深度计算&#xff0c;从而提升光场相机的三维重建的精度&#xff0c;需要实现精确…

PgSQL之WITH Queries/Statement

PostgreSQL WITH 子句 在 PostgreSQL 中&#xff0c;WITH 子句提供了一种编写辅助语句的方法&#xff0c;以便在更大的查询中使用。 WITH 子句有助于将复杂的大型查询分解为更简单的表单&#xff0c;便于阅读。这些语句通常称为通用表表达式&#xff08;Common Table Express…

《Kubernets证书篇:基于Kylin V10+ARM架构CPU修改K8S 1.26.15版本证书时间限制》

一、背景 Kubernetes 默认的证书有效期只有1年&#xff0c;因此需要每年手动更新一次节点上面的证书&#xff0c;特别麻烦而且更新过程中可能会出现问题&#xff0c;因此我们要对 Kubernetes 的 SSL 证书有效期进行修改&#xff0c;这里将证书的时间限制修改为100年。 环境信息…

视频国标学习

总体介绍 GB/T28181协议&#xff0c;全名叫《安全防范视频监控联网系统信息传输、交换、控制技术要求》&#xff0c;是由中国国家标准委员会发布的一种国家级的标准。它主要对视频监控系统的各个方面做了明确的规定&#xff0c;使得不同厂商生产的视频监控设备能够相互连通&am…

JavaScript之Proxy详解

文章的更新路线&#xff1a;JavaScript基础知识-Vue2基础知识-Vue3基础知识-TypeScript基础知识-网络基础知识-浏览器基础知识-项目优化知识-项目实战经验-前端温习题&#xff08;HTML基础知识和CSS基础知识已经更新完毕&#xff09; 正文 Proxy是JavaScript中的一个强大而灵活…

linux 自定义快捷指令(docker

vi /root/.bashrc alias disdocker images alias dpsdocker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}" 保存退出后使用sourece /root/.bashrc 让其立即生效 sourece /root/.bashrc

【C 数据结构】栈

文章目录 【 1. 基本原理 】栈的分类 【 2. 动态链表栈 】2.1 双结构体实现2.1.0 栈的节点设计2.1.1 入栈2.1.2 出栈2.1.3 遍历2.1.4 实例 2.2 单结构体实现2.2.0 栈的节点设计2.2.1 入栈2.2.2 出栈2.2.3 实例 【 3. 顺序栈 】3.1 入栈3.2 出栈3.3 实例 【 1. 基本原理 】 栈&…

牛客网刷题 :BC50 你是天才吗

描述 据说智商140以上者称为天才&#xff0c;KiKi想知道他自己是不是天才&#xff0c;请帮他编程判断。输入一个整数表示一个人的智商&#xff0c;如果大于等于140&#xff0c;则表明他是一个天才&#xff0c;输出“Genius”。 输入描述&#xff1a; 多组输入&#xff0c;每…

【opencv】示例-videocapture_microphone.cpp 使用OpenCV库实现的音频捕获

#include <opencv2/core.hpp> // 包含OpenCV核心功能头文件 #include <opencv2/videoio.hpp> // 包含OpenCV视频输入输出头文件 #include <opencv2/highgui.hpp> // 包含OpenCV高层GUI头文件 #include <iostream> // 包含标准输入输出流头文件using na…

SS3D翻译

SS3D AbstractIntroductionRelated WorkFully-Supervised 3D Object DetectionWeakly/Semi-Supervised 3D Object DetectionSparsely-Supervised 2D Object Detection MethodOverall FrameworkArchitecture of DetectorMissing-Annotated Instance Mining Module 缺失注释实例挖…

leetcode-链表中间节点

876. 链表的中间结点 题目 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表只有一个中间…

基于STM32的RFID智能门锁系统

本文针对RFID技术&#xff0c;着重研究了基于单片机的智能门锁系统设计。首先&#xff0c;通过链接4*4按键模块与主控STM32&#xff0c;实现了多种模式&#xff0c;包括刷卡开锁、卡号权限管理、密码开锁、修改密码、显示实时时间等功能。其次&#xff0c;采用RC522模块与主控S…

GitHub登录收不到邮箱验证码

由于长时间没有登录GitHub&#xff0c;浏览器可能清除了相应的cookie信息&#xff0c;所以需要对应绑定邮箱进行验证&#xff0c;但因为邮箱长时间没有收到验证码&#xff0c;所以给到以下一种可能解决的方法&#xff1a; 需要输入验证码进行验证 我们可以打开QQ邮箱&#xff0…

Wpf 使用 Prism 实战开发Day19

待办事项功能页面完善以及优化 概要&#xff1a; 由于待办事项功能页&#xff0c;数据已正常渲染出来了。但页面新增&#xff0c;查询&#xff0c;修改&#xff0c;删除等功能还未实现。本章节来实现页面的请求后台实现CURD&#xff08;增删改查&#xff09; 一.待办事项查询…

UE5不打包启用像素流 ubuntu22.04

首先查找引擎中像素流的位置&#xff1a; zkzk-ubuntu2023:/media/zk/Data/Linux_Unreal_Engine_5.3.2$ sudo find ./ -name get_ps_servers.sh [sudo] zk 的密码&#xff1a; ./Engine/Plugins/Media/PixelStreaming/Resources/WebServers/get_ps_servers.sh然后在指定路径中…

分布式锁-redission锁的MutiLock原理

5.5 分布式锁-redission锁的MutiLock原理 为了提高redis的可用性&#xff0c;我们会搭建集群或者主从&#xff0c;现在以主从为例 此时我们去写命令&#xff0c;写在主机上&#xff0c; 主机会将数据同步给从机&#xff0c;但是假设在主机还没有来得及把数据写入到从机去的时…