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

embedded/2024/9/24 17:31:58/
xmlns="http://www.w3.org/2000/svg" style="display: none;">

参考:
对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.ppmy.cn/embedded/9290.html

相关文章

大白话!go语言中的指针、指针类型的方法接收器

go语言中的指针使用起来的比较简单。应用如下&#xff1a; 1.普通的对象取地址&#xff0c;获取对象值 符号&&#xff0c;取地址符&#xff0c;可以取变量的地址&#xff0c;或结构体对象的地址等。符号*&#xff0c;是从地址中取值&#xff08;根据栈中存储地址&#xf…

实现I.MX6ULL开发板与Windows和Ubuntu系统之间的通信

虚拟机与主机之间的连接方式确实包括桥接模式、NAT模式和仅主机模式。 桥接模式&#xff08;Bridged&#xff09;&#xff1a;在桥接模式下&#xff0c;虚拟机通过虚拟交换机直接连接到主机的物理网络上&#xff0c;就像一台独立的物理机器一样&#xff0c;拥有自己的IP地址&a…

Kotlin语法快速入门--条件控制和循环语句(2)

Kotlin语法入门–条件控制和循环语句&#xff08;2&#xff09; 文章目录 Kotlin语法入门--条件控制和循环语句&#xff08;2&#xff09;二、条件控制和循环语句1、if...else2、when2.1、常规用法2.2、特殊用法--并列&#xff1a;2.3、特殊用法--类型判断&#xff1a;2.4、特殊…

设计模式在芯片验证中的应用——策略

1. 策略模式 策略模式是一种行为设计模式&#xff0c; 它能让你定义一系列算法&#xff0c; 并将每种算法分别放入独立的类中&#xff0c; 以使算法的对象能够相互替换。 在RTL设计中可能包含了复杂的多个访问仲裁逻辑&#xff0c;使用了多种算法来确定访问内存优先级顺序&am…

2024年04月18日优雅草便民tools开源-git以及dcloud同步-长期更新

优雅草小工具-数据来自优雅草api赋能 优雅草小工具-数据来自优雅草api赋能-优雅草便民工具是一款由成都市一颗优雅草科技有限公司打造的便民查询公益工具&#xff0c;2024年1月17日正式发布v1.0.0版本&#xff0c;本工具为了方便大众免费使用&#xff0c;本生活小工具会陆续加入…

JMeter--后置处理器--JSON提取器(JSON Extractor)

数据关联&#xff0c;可以通过JsonPath提取所需要的值&#xff0c;功能非常强大&#xff08;注意取样器返回必须为 Json&#xff09;&#xff1b;底层采用jackson实现&#xff1b; 右键 >>> 添加 >>> 后置处理器 >>> JSON提取器&#xff08;JSON E…

【MySQL 数据宝典】【内存结构】- 003 Change Buffer 详解

一、 Change Buffer基本概念 Change Buffer&#xff1a;写缓冲区,是针对二级索引(辅助索引) 页的更新优化措施。 作用: 在进行DML操作时&#xff0c;如果请求的是 辅助索引&#xff08;非唯一键索引&#xff09;没有在缓冲池 中时&#xff0c;并不会立刻将磁盘页加载到缓冲池…

DIY mybatisPlus的分页插件

目录 起因修改定义接口重写MyPage的方法 实践测试 起因 在我们通过list返回的列表页&#xff0c;出现了一个需要数据合计的需求&#xff0c;例如一个订单1块钱&#xff0c;那么所有订单加起来多少钱&#xff0c;那么list一般都通过分页返回&#xff0c;而统计所有订单又不能只…