316_C++_xml文件解析成map,可以放到QT表格上, 且 xml、xlsx文件可以互相解析

xml文件例如:

在这里插入图片描述<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <TrTable> <tr id="0" label="TR_PB_CH" text="CH%2"/> <tr id="4" label="TR_PB_CHN" text="Channel"/> <tr id="5" label="TR_PB_WARNING" text="Warning!"/> <tr id="6" label="TR_PB_NOTICE" text="Notice"/> <tr id="7" label="TR_PB_DEFAULT" text="Default"/> <tr id="8" label="TR_PB_SAVE" text="Save"/> <tr id="17" label="TR_PB_CLEAR" text="add-left1"/> <tr id="18" label="TR_PB_ALL" text="add-left2"/> <tr id="19" label="TR_PB_CLEAR-2" text="add-left3"/> <tr id="20" label="TR_PB_ALL-2" text="add-left4"/> <tr id="21" label="TR_PB_ALL-2" text="add-left4"/> <tr id="150524" label="TR_IPC_ACTIVE_PASSWD_MODE2" text="add-left5"/> </TrTable>

xlsx文件例如:

在这里插入图片描述

表格显示效果:

在这里插入图片描述:多个xml文件打开


在这里插入图片描述
:单个xml文件打开

xml文件解析成map:ProcessXMLFilesToMap

-------------------------------.h-------------------------------
#include <vector>
#include <string>
#include <map>
#include <QFileInfo>
#define CREATE_XLSX // 采用xlsx
using namespace std;
struct Translation {
    string label;
    vector<string> texts;
};

struct TextsInfo {
	int id;
    string label;
    string text;
};
-------------------------------.cpp-------------------------------
std::map<int, Translation> ProcessXMLFilesToMap(std::vector<std::string>& xmlFiles)
{
    std::map<int, Translation> translations;
    int num = 0;
    for (const auto& xmlFile : xmlFiles) {
        ParseXMLToMap(++num, xmlFile, translations);
    }

    return translations; //返回给表格所需的map
}

// 解析XML文件并填充translations map
void ParseXMLToMap(int fileNum, const std::string& xmlFilePath, std::map<int, Translation>& translations) 
{
    QTextCodec *code = QTextCodec::codecForName("GB2312"); //上层,转成中文后,可以解析使用中文路径
    string selectedFile = code->fromUnicode(xmlFilePath.c_str()).data();
    std::ifstream file(selectedFile.c_str());
    if (!file.is_open()) {
        std::cerr << "Error opening file: " << xmlFilePath << std::endl;
        return;
    }

    std::string line;
    bool inTrTag = false;
    std::string currentLabel;
    std::vector<std::string> currentTexts;
    int currentId = -1;

    while (std::getline(file, line)) {
        if (!line.empty() || line[0] == '<') {
            if (inTrTag) {
                if (currentId != -1) {
					if (translations.find(currentId) != translations.end()) 
					{	
						// 该ID存在在map中,就进行当前位置的插入
						translations[currentId].texts.insert(translations[currentId].texts.end(), currentTexts.begin(), currentTexts.end());
                    }
					else 
					{
						// 该ID不存在在map中,就进行尾部的插入
						Translation translation;
						translation.label = currentLabel;
						while(translation.texts.size() < (fileNum - 1))
						{
							translation.texts.push_back("");
						}
						translation.texts.insert(translation.texts.end(), currentTexts.begin(), currentTexts.end());
						translations[currentId] = translation;
					}
                }
                // 一轮赋值完毕,这些用了暂时保存数据的变量、容器就要clear清空,方便下次继续
                inTrTag = false;
                currentLabel.clear();
                currentTexts.clear();
                currentId = -1;
            }
            // 开始逐行解析
            size_t trPos = line.find("<tr");
            if (trPos != std::string::npos) {
                size_t idPos = line.find("id=\"", trPos);
                size_t labelPos = line.find("label=\"", trPos);
                size_t textPos = line.find("text=\"", trPos);

                if (idPos != std::string::npos && labelPos != std::string::npos && textPos != std::string::npos) {
                    std::string idStr = line.substr(idPos + 4, line.find('"', idPos + 4) - idPos - 4);
                    std::string labelStr = line.substr(labelPos + 7, line.find('"', labelPos + 7) - labelPos - 7);
                    std::string textStr = line.substr(textPos + 6, line.find("/>", textPos + 6) - textPos - 6);
                    while(!textStr.empty() && textStr.back() != '\"')
                        textStr.pop_back();

                    if(!textStr.empty())
                        textStr.pop_back();
						

                    currentId = std::stoi(idStr);
                    currentLabel = labelStr;
                    currentTexts.push_back(textStr);
                    inTrTag = true;
                }
            }
        }
		else if (inTrTag) 
		{
            currentTexts.push_back(line);
        }
    }

    if (inTrTag && currentId != -1) 
	{
	    if (translations.find(currentId) != translations.end()) 
		{	
	        //translations[currentId].texts.push_back(currentTexts);	
			translations[currentId].texts.insert(translations[currentId].texts.end(), currentTexts.begin(), currentTexts.end());
	    } 
		else 
		{
	        Translation translation;
	        translation.label = currentLabel;
			while(translation.texts.size() < (fileNum - 1))
			{
				translation.texts.push_back("");
			}
			
			translation.texts.insert(translation.texts.end(), currentTexts.begin(), currentTexts.end());
	        translations[currentId] = translation;
	    }
    }

    file.close();
	if(fileNum > 1) // 多个文件,就依照第一个文件的ID作为依据,拼接后续文件的text而已
		CompleteMissingTexts(fileNum, translations);	
}

void CompleteMissingTexts(int fileNum, std::map<int, Translation>& translations)
{
    for (auto& pair : translations)
    {
		Translation *translation = &pair.second;

		while(translation->texts.size() < fileNum)
		{
			translation->texts.push_back(translation->texts[0]);
		}
	}
}

-------------------------------QT表格xml打开操作.h-------------------------------
class xmlFileDoc : public FileDoc // 继承自自写类
{
    Q_OBJECT
public:
    explicit xmlFileDoc(QWidget *parent);
    ~xmlFileDoc();
    void openFile(QString& aFileName); //打开文件
    void openFiles(std::vector<std::string>& FileNames);
    void refreshTable(std::map<int, Translation> trans);
    void closeEvent(QCloseEvent *event);
    void saveFile();
    std::vector<TextsInfo> textVectorInfos();
};
-------------------------------QT表格xml打开操作.cpp-------------------------------
void xmlFileDoc::openFiles(std::vector<std::string>& FileNames)
{
	m_type = MUL_XML_FILE;
    m_files = FileNames;
    std::map<int, Translation> trans = ProcessXMLFilesToMap(FileNames);
    refreshTable(trans);
	m_customTableWidget->setFileType(false);
}

void xmlFileDoc::refreshTable(std::map<int, Translation> trans)
{
    if (m_files.size() == 0)
    {
        return;
    }
    QSignalBlocker blocker(m_customTableWidget);// 阻塞表格其他地方的信号,例如itemchanged信号
    m_customTableWidget->setRowCount(trans.size());
    m_customTableWidget->setColumnCount(m_files.size()+2);
    m_customTableWidget->setRestrictedColumns(m_files.size()+2);

    QStringList horizontalHeaderLabels;
    horizontalHeaderLabels << "ID" << "Label";

    for (int i = 0; i < m_files.size(); i++)
    {
        std::string filename = extractFileName(m_files[i]);
        horizontalHeaderLabels << filename.c_str();
    }

    m_customTableWidget->setHorizontalHeaderLabels(horizontalHeaderLabels);

    int row = 0;
    for (auto &pair : trans)
    {
        int col = 0;
        QTableWidgetItem *item;
        item = new QTableWidgetItem(QString::number(pair.first));
        m_customTableWidget->setItem(row,col++,item);
        item = new QTableWidgetItem(QString::fromStdString(pair.second.label));
        m_customTableWidget->setItem(row,col++,item);
        for (int num = col; num < m_files.size()+2; num++)
        {
            item = new QTableWidgetItem(QString::fromStdString(pair.second.texts[num - 2]));
            m_customTableWidget->setItem(row,num,item);
        }
        row++;
    }
}

void xmlFileDoc::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HZNUCTF第五届校赛实践赛初赛 Web方向 WriteUp

ezssti 很简单的ssti 源码给了&#xff0c;调用Eval即可执行命令 package mainimport ("fmt""net/http""os/exec""strings""text/template" )type User struct {Id intName stringPasswd string }func (u User) Ev…

如何在阿里云主机上安装FreeBSD14系统

文章目录 在阿里云主机上安装FreeBSD14系统准备阿里云云主机识别目标磁盘下载 FreeBSD14解压缩 FreeBSD14系统镜像创建可启动的磁盘启动 FreeBSD14在阿里云主机上安装FreeBSD14系统 阿里云主机不支持 FreeBSD14 系统的镜像,因此需要手动进行安装。 准备阿里云云主机 在阿里云…

解决Git 不相关的分支合并

可以直接调到解决方案,接下来是原因分析和每步的解决方式 问题原因: 我之前在自己本机创建了一个初始化了Git仓库,后来有在另一个电脑初始化仓库,并没有clone自己在本机Git远程仓库地址,导致Git历史版本不相关 错误信息 From https://gitee.com/to-uphold-justice-for-other…

文字转语音工具:GPT-SoVITS

诸神缄默不语-个人CSDN博文目录 OpenAI官方的TTS模型我在这篇博文中给出了使用教程&#xff1a;ChatGPT 3.5 API的调用不全指南&#xff08;持续更新ing…&#xff09; - 知乎 但是OpenAI的TTS对中文支持不好&#xff0c;有一种老外说中文的美&#xff0c;所以本文介绍另一个…

Amazon SES邮箱API发送邮件的步骤是什么?

Amazon SES邮箱API发送邮件怎么配置&#xff1f;如何用邮箱API发送邮件&#xff1f; 在数字化时代&#xff0c;电子邮件已成为企业与个人之间沟通的重要桥梁。那么&#xff0c;使用Amazon SES邮箱API发送邮件的步骤究竟是怎样的呢&#xff1f;接下来&#xff0c;就让AokSend来…

IDEA远程调试debug

IDEA远程调试debug jar包启动脚本配置IDEA配置 通俗的说&#xff1a;本地有代码&#xff0c;服务器项目出现问题&#xff0c;环境的中间件配置不同&#xff0c;用idea远程调试&#xff0c;能快速定位问题&#xff0c;解决问题。 jar包启动脚本配置 jdk5-8写法 java -Xdebug -…

ChatGPT在遥感领域中的应用

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境&#xff0c;是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型&#xff0c;在理解和生成人类语言方面表现出了非凡的能力。本课程重点介绍ChatGPT在遥感中的应用&#xff0c;人工智…

MCU的最佳存储方案CS创世 SD NAND

MCU的最佳存储方案CS创世 SD NAND 写在最前面MCU是什么CS创世 SD NAND 6大优势 写在最前面 转载自 雷龙官网 MCU是什么 大家都知道MCU是一种"麻雀"虽小&#xff0c;却"五脏俱全"的主控。它的应用领域非常广泛&#xff0c;小到手机手表&#xff0c;大到航空…

【Kafka】Kafka Tool工具的使用

抖音视频 https://www.douyin.com/user/self?modal_id7123007128150901256&showTablike CSDN文档 https://blog.csdn.net/qq_43961619/article/details/109381849

Blind Image Super-Resolution: A Survey and Beyond

TPAMI2023 问题定义 未知图像的退化过程&#xff08;和之前假定bicubic等一个固定且已知的退化过程相对比&#xff09;&#xff0c;由LR恢复HR&#xff1b;退化来源&#xff08;不同的图像采集设备&#xff0c;数字信号处理成可见图像的过程中图像处理算法引入的噪声&#xff…

机器学习——模型融合:Stacking算法

机器学习——模型融合&#xff1a;Stacking算法 在机器学习中&#xff0c;模型融合是一种常用的方法&#xff0c;它可以提高模型的泛化能力和预测性能。Stacking算法&#xff08;又称为堆叠泛化&#xff09;是一种强大的模型融合技术&#xff0c;它通过组合多个基本分类器的预…

PyCharm连接数据库代码解析

1.先导入pymysql模块 在PyCharm中用清华镜像快速安装包 依次把ip地址和账号名、密码、数据库名、端口、编码输入 2.创建游标 游标&#xff1a;是数据库中的一个概念&#xff0c;我们执行sql查询语句时&#xff0c;大部分情况都会得到很多条结果&#xff0c;我们取出这些返回结…

python 无处不在的二分搜索

我们知道二分查找算法。二分查找是最容易正确的算法。我提出了一些我在二分搜索中收集的有趣问题。有一些关于二分搜索的请求。我请求您遵守准则&#xff1a;“我真诚地尝试解决问题并确保不存在极端情况”。阅读完每个问题后&#xff0c;最小化浏览器并尝试解决它。 …

数学建模--蒙特卡罗法MATLAB代码保姆式解析

1.简单介绍 2.思想的实际运用 我们利用蒙特卡罗法的思想求解圆周率π的值&#xff0c;这里求得的肯定是近似值&#xff0c;我们是通过大量的模拟实验&#xff0c;利用概率求解的&#xff0c;但是这个值和我们的精确值之间还是有一定的误差的&#xff1b; 我们的思想就是在半径为…

【Lattice FPGA 开发】Diamond的使用

文章目录 Diamond的使用教程界面器件查看与更改管脚分配RTL分析图查看 第三方工具关联Notepad 问题与解决管脚被分类到unconnected&#xff0c;导致无法分配管脚 Diamond的使用教程 【Lattice FPGA 开发】Diamond的工程建立、文件输入、ip核配置、管脚配置、综合及布线以及下载…

python/pygame 挑战魂斗罗 笔记(二)

一、建立地面碰撞体&#xff1a; 现在主角Bill能够站立在游戏地图的地面&#xff0c;是因为我们初始化的时候把Bill的位置固定了self.rect.y 250。而不是真正的站在地图的地面上。 背景地图是一个完整的地图&#xff0c;没有地面、台阶的概念&#xff0c;就无法通过碰撞检测来…

【分治】Leetcode 排序数组

题目讲解 912. 排序数组 算法讲解 我们这里使用三指针&#xff0c;将数组分成三块&#xff1a;<key 和 key 和 >key,如果当前指针指向的数字<key&#xff0c;我们就swap(nums[left]), nums[i] 。如果当前的数字key &#xff0c;就让i。如果当前的数字>key&…

大屏数字字体+渐变色

vue数据大屏使用数字字体_vue数字字体-CSDN博客 用css实现文字字体颜色渐变的三种方法_css 字体颜色渐变-CSDN博客

DNS服务器配置与管理(2)——BIND部署DNS

在Linux上配置DNS的常用软件是BIND&#xff08;Berkeley Internet Name Domain Service&#xff0c;BIND&#xff09;&#xff0c;它是一款实现DNS服务器的开放源码软件。本文详细介绍了在CentOS7上安装并配置Bind软件。 一、Bind软件介绍 BIND包最初是在 1980 年代初在加州大…

35岁再去学程序员靠谱吗?

不亚于49年入国Jun。35岁的程序员都已经在找后路了…… 总结一句话&#xff1a;35岁自学程序员赚点小钱可以&#xff0c;当主业糊口不行&#xff01; 首先&#xff0c;程序员这行吃青春饭是真的。虽说国外有很多程序员可以写代码到70岁&#xff0c;但国内的现状是35岁就会淘汰一…
最新文章