QT调用Tinyxml2库解析XML结构文件

在学习SVG结构的时候,发现SVG结构可以通过以XML文件直接解析,所以就去了解了Tinyxml2库的使用,相关教程也比较多。
个人感觉Tinyxml2库比官方的XML解析库更好用,这里做个技术总结,记录Tinyxml2库解析XML文件结构的简单使用。

目录导读

    • Tinyxml2库 介绍(文言一心)
    • 使用CMAKE 和 MSVC 2017 编译 Tinyxml2库
    • QT 调用 **tinyxml2.lib** 解析XML
      • 遍历所有节点
      • 将XML节点 加载到QTreeWidget 控件上
      • 其他TinyXML2库操作XML示例:

Tinyxml2库 介绍(文言一心)

TinyXML-2 是一个简单、小巧且功能强大的C++ XML解析库,它是TinyXML的改进和扩展版本。该库专注于易用性和性能,提供了对XML文档的读取、修改和创建功能。以下是TinyXML-2的主要特点:

  • DOM风格API: TinyXML-2采用了Document Object Model(DOM)风格的API,允许开发者以树形结构的方式操作XML数据。这意味着开发者可以轻松地遍历、查询和修改XML文档。
  • 轻量级: TinyXML-2的代码量小,不依赖外部库,因此非常适合嵌入式系统和移动设备。由于其小巧的体积和高效的实现,它在处理XML文档的速度上表现出色。
  • 易于使用: TinyXML-2的API设计直观、简洁,类和方法命名直观(如XMLNode、XMLElement等),使得学习成本较低,易于理解和集成到项目中。
  • 错误处理: TinyXML-2提供了一套全面的错误检查机制。如果遇到无效的XML格式,它会抛出异常或返回错误代码,帮助开发者快速定位问题。
    支持解析和生成:TinyXML-2支持从字符串或文件中解析XML文档,并且可以生成格式良好的XML文本。它能够处理各种节点类型,如元素、属性、文本、注释等。
  • 跨平台: TinyXML-2完全基于标准C++编写,可以在多种操作系统和编译器环境下运行,包括Windows、Linux、Mac OS X等。

总的来说,TinyXML-2是一个功能强大、易于使用且跨平台的C++ XML解析库,适用于各种需要处理XML数据的场景。

Github: https://github.com/leethomason/tinyxml2

使用CMAKE 和 MSVC 2017 编译 Tinyxml2库

参考:xml开发笔记(一):tinyXml2库介绍、编译和工程模板
下载最新GitHub的项目通过CMAKE编译:
Configure选择MSCV2017编译器和X64平台:
请添加图片描述
直接ConfigureGenerate生成VS2017项目,可能是编译器或版本文件没有出现任何异常…
在这里插入图片描述
项目工程直接生成 tinyxml2.lib 没有了dll文件。
xmltest.cpp 文件为调用示例,建议参考。
在这里插入图片描述

QT 调用 tinyxml2.lib 解析XML

将项目中的 tinyxml2.htinyxml2.cpptinyxml2.lib 放在项目目录下。
在这里插入图片描述

#include "tinyxml2/tinyxml2.h"

using namespace tinyxml2;
using namespace std;

//! tinyxml2.lib 绝对路径
#pragma comment(lib,"E:\\data-bank\\Git\\Qt_XML_Lanalysis\\Qt_XML_Lanalysis\\XML_LAnalysis_UI\\tinyxml2\\tinyxml2.lib")

遍历所有节点

加载XML文件遍历所有节点,并输出节点中的所有属性值
参考:tinyxml/tinyxml2遍历所有节点

#include <QDebug>
#include <QObject>
#include <QFileInfo>

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>


void Lib_XmlReadWrite::GetEleValue(XMLElement * element)
{
    for (XMLElement* currentele = element->FirstChildElement(); currentele; currentele = currentele->NextSiblingElement())
    {
        XMLElement* tmpele = currentele;
        if (currentele->Name() != NULL||currentele->GetText() != NULL)
            qDebug() <<"-->" << currentele->Name() << ":" << currentele->GetText() ;
		
        if(tmpele->FirstAttribute()!=NULL)
        {
            //! 输出所有属性值
            for (const XMLAttribute* var =tmpele->FirstAttribute(); var;var=var->Next()) {
                qDebug()<<"---->" <<var->Name()<<" : "<<var->Value();
            }
        }
		
		//! 有子节点继续加载
        if (!tmpele->NoChildren())
            GetEleValue(tmpele);
    }
}


void Lib_XmlReadWrite::LoadXML(QString xml)
{
    QFileInfo info("C:\\Users\\admin\\Desktop\\textxml\\text_xml5.xml");

    qDebug()<< "LoadXML -->"<<info.exists();
    XMLDocument doc;
    doc.LoadFile(info.absoluteFilePath().toStdString().c_str());
    qDebug()<<doc.ErrorIDToName(doc.ErrorID());

    qDebug()<< doc.FirstChild()->FirstChildElement()->Name();
    qDebug()<<doc.RootElement()->Name();
    qDebug()<<"-----------------------------------";
    GetEleValue(doc.RootElement());


}

将XML节点 加载到QTreeWidget 控件上

通过 QTreeWidgetItem 结构将XML相关结构显示到 QTreeWidget 控件上。
值得注意的是 如果一个文件有多个根节点可以通过
for (XMLElement* root = doc.RootElement(); root; root = root->NextSiblingElement())
遍历所有根节点。


bool Lib_XmlReadWrite::LoadTreeWidget(QString xmlpath,QTreeWidgetItem* & item,QString& ErrorStr)
{
    //! 判断文件是否存在!
   QFileInfo xmlInfo(xmlpath);
    if(!xmlInfo.exists())
    {
        ErrorStr=("文件["+QString(xmlpath)+"]不存在!");
        return false;
    }

    //! 加载xml格式文件
    doc.Clear();;
    doc.LoadFile(xmlInfo.absoluteFilePath().toStdString().c_str());

    if(doc.ErrorID()!=XML_SUCCESS)
    {
        ErrorStr=("解析失败:"+QString(doc.ErrorStr()));
        return false;
    }

    //! 添加文件根目录
    item=new QTreeWidgetItem(QStringList()<<QString(xmlInfo.baseName())<<""<<xmlInfo.absoluteFilePath());
    //! 不一定只有一个节点
    for (XMLElement* root = doc.RootElement(); root; root = root->NextSiblingElement())
    {
        //! XML子节点
        QTreeWidgetItem* rootitem=new QTreeWidgetItem(QStringList()<<QString(root->Name())<<""<<root->GetText(),QTreeWidgetItem::UserType);
        RecursionElement(root,rootitem);
        item->addChild(rootitem);
    }
    return true;
}

void Lib_XmlReadWrite::RecursionElement(XMLElement * element,QTreeWidgetItem* & item)
{
    //! 查找当前 element 子节点
    for (XMLElement* currentele = element->FirstChildElement(); currentele; currentele = currentele->NextSiblingElement())
    {
        XMLElement* tmpele = currentele;
        QTreeWidgetItem* childitem=new QTreeWidgetItem(QStringList()<<tmpele->Name()<<""<<tmpele->GetText());
        if(tmpele->FirstAttribute()!=NULL)
        {
            //! 添加属性值
            for (const XMLAttribute* var =tmpele->FirstAttribute(); var;var=var->Next()) {
                QTreeWidgetItem* attritem=new QTreeWidgetItem(QStringList()<<""<<var->Name()<<var->Value(),QTreeWidgetItem::UserType);
                attritem->setToolTip(2,var->Value());
                childitem->addChild(attritem);
            }
        }

        //! 查找 tmpele 子节点
        if (!tmpele->NoChildren())
            RecursionElement(tmpele,childitem);

        item->addChild(childitem);
    }
}

/*!
//! 调用
void MainWindow::LoadXMLStructure(QString text)
{
    ui->treeWidget->clear();
    ui->treeWidget->setHeaderLabels(QStringList()<<"节点"<<"属性"<<"业务值");
    ui->treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);

    if(text=="")
        return;

    QString ErrorStr;
    QTreeWidgetItem* item;
    bool isbol=Lib_XmlReadWrite::LoadTreeWidget(text,item,ErrorStr);

    if(!isbol)
    {
        qDebug()<<"[ErrorStr] "<<ErrorStr;
        ui->statusBar->showMessage(ErrorStr,0);
    }
    else
    {
        ui->treeWidget->addTopLevelItem(item);
        ui->treeWidget->expandAll();
    }
}
*/


效果:
在这里插入图片描述

其他TinyXML2库操作XML示例:

TinyXML2库解析xml感觉比Qt的QXmlStreamReader这种更好用,
但是不适合用来解析HTML文件,HTML文件中,像<link>这种节点会直接解析失败。
参考:

  • TinyXML2使用方法及示例
  • 官方示例 xmltest.cpp 文件

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

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

相关文章

计组期末必考大题

一.寻址方式详解 1.直接寻址 指令地址码直接给到操作数所在的存储单元地址 2.间接寻址 A为操作数EA的地址 3.寄存寻址 4.寄存器间接寻址 5.变址寻址 6.基地址寻址 7.小结 二、指令周期详解 一、基本概念 指令周期:去除指令并执行指令所需要的时间指令周期:由若干个CPU周…

分割训练日志的可视化

这一部分主要是将mmdetection训练得到的json文件可视化&#xff0c;代码主要源于github&#xff0c;具体哪一个忘记了&#xff08;readme里面没有原址…&#xff09;是专门做的mmdetection 结果可视化的&#xff0c;非常强&#xff01;&#xff01;。使用时如果出现keyerror的话…

Servlet的request对象

request对象的继承关系 1.HttpServletRequest接口继承了ServletRequest接口&#xff0c;对其父接口进行了扩展&#xff0c;可以处理满足所有http协议的请求 2.HttpServletRequest和ServletRequest都是接口&#xff0c;不能创建对象&#xff0c;因此在tomcat底层定义实现类并创…

文本三剑客之 sed 编辑器

一.sed 概述 1.sed 介绍 sed是一种流编辑器&#xff0c;流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理数据流中的数据&#xff0c;这些命令要么从命令行中输入&#xff0c;要么存储在一个 命令文本文件中。 2.sed 的工…

基于python实现搜索的目标站点内容监测系统

基于python实现搜索的目标站点内容监测系统 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系统功能实现 登录页面 后台的登录一般是为了管理员的管理方便进行一个用户权限的验证。也是为管理员提供的唯…

【贪心算法题目】

1. 柠檬水找零 这一个题目是一个比较简单的模拟算法&#xff0c;只需要根据手里的钱进行找零即可&#xff0c;对于贪心的这一点&#xff0c;主要是在20元钱找零的情况下&#xff0c;此时会出现两种情况&#xff1a;10 5 的组合 和 5 5 5 的组合&#xff0c;根据找零的特点&a…

DVWA代码审计--SQL注入

NO.1 Low 首先来看下代码 <?php if( isset( $_REQUEST[ Submit ] ) ) { // Get input $id $_REQUEST[ id ]; // Check database $query "SELECT first_name, last_name FROM users WHERE user_id $id;"; $result mysql_query( $query ) or die( <pre>…

vue中数据已经改变了,但是table里面内容没更新渲染!

解决方案&#xff1a; 给table或者el-table标签上添加一个动态key值&#xff0c;只要数据发生改变&#xff0c;key值变动一下即可 标签上&#xff1a; :key“timeStamp” 初始data&#xff1a;timeStamp:0, 更新数据&#xff1a;this.timeStamp 这样每次更新数据&#xff…

微信小程序---小程序文档配置(2)

一、小程序文档配置 1、小程序的目录结构 1.1、目录结构 小程序包含一个描述整体程序的 app 和多个描述各自页面的 page 一个小程序主体部分由三个文件组成&#xff0c;必须放在项目的根目录 比如当前我们的《第一个小程序》项目根目录下就存在这三个文件&#xff1a; 1…

Android 几个简单的自定义对话框介绍

Android 几个简单的自定义对话框介绍 文章目录 一、前言二、对话框相关内容1、效果2、对话框显示的调用代码&#xff08;1&#xff09;原生对话框代码&#xff1a;&#xff08;2&#xff09;自定义对话框代码&#xff1a; 3、对话框SweetAlertDialog 主要实现代码&#xff1a;4…

《Python编程从入门到实践》day37

# 昨日知识点回顾 制定规范、创建虚拟环境并激活&#xff0c;正在虚拟环境创建项目、数据库和应用程序 # 今日知识点学习 18.2.4 定义模型Entry # models.py from django.db import models# Create your models here. class Topic(models.Model):"""用户学习的…

【课后练习分享】Java用户注册界面设计和求三角形面积的图形界面程序

目录 java编程题&#xff08;每日一练&#xff09;&#xff1a; 问题一的答案代码如下&#xff1a; 问题一的运行截图如下&#xff1a; 问题二的答案代码如下&#xff1a; 问题二的运行截图如下&#xff1a; java编程题&#xff08;每日一练&#xff09;&#xff1a; 1.…

windows安装官方正版notepad++

一 、notepad介绍 Notepad 是一个免费的、开源的文本编辑器&#xff0c;主要面向程序员和高级用户。以下是 Notepad 的特点&#xff1a; 跨平台&#xff1a; 虽然主要为 Windows 平台设计&#xff0c;但可以通过 Wine 在 Linux 和 macOS 上运行。 语法高亮&#xff1a; 自动识…

Dubbo生态之初识dubbo协议

1.RPC框架 在java的发展中&#xff0c;随着业务的越来越庞大&#xff0c;单体架构的工作繁琐且耦合度高&#xff0c;因此单体架构过渡到了分布式架构&#xff0c;而分布式架构就必然涉及到各个服务之间的远程通信(RPC框架)&#xff0c;RPC框架如图所示: 工作流程: a.客户端调…

ElasticSearch 查询优化之skipped shards

文章目录 问题通过timeDate查询 问题 PUT test_01 {"settings": {"number_of_shards": 50}, "mappings": {"properties": {"createTimeDate": {"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis&…

对列表进行统计和计算

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Python的列表提供了内置的一些函数来实现统计、计算的功能。下面介绍几种常用的功能。 &#xff08;1&#xff09;获取指定元素出现的次数 使用列表…

汇聚荣科技有限公司怎么样?

在众多企业中&#xff0c;汇聚荣科技有限公司以其独特的发展模式和市场定位引起了人们的关注。对于这个问题&#xff0c;答案并非简单的好与坏&#xff0c;而需要从多个维度进行深入分析。 一、公司背景与发展历程汇聚荣科技有限公司成立于何年何地&#xff0c;由谁创立&#x…

民国漫画杂志《时代漫画》第17期.PDF

时代漫画17.PDF: https://url03.ctfile.com/f/1779803-1248612629-85326d?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络&#xff01;

蓝牙模块七种工作模式——蓝牙Mesh组网工作模式

蓝牙Mesh组网模块技术在2017年得到SIG批准&#xff0c;这是一种独立的网络技术&#xff0c;兼容4及5系列蓝牙协议。它把蓝牙设备作为信号中继站&#xff0c;利用低功耗蓝牙广播的方式进行信息收发&#xff0c;蓝牙Mesh组网技术拓展了蓝牙的通讯关系&#xff0c;打破了以往蓝牙设…

环信 X 星野| 共创沉浸式 AI 互动体验

大模型技术的发展使虚拟人更加智能和情感丰富&#xff0c;推动人与 AI 智能体互动体验进入新时代。星野App 是一款沉浸式 AI 内容社区&#xff0c;短短几个月日活过百万。虽然市面上的社交产品很多&#xff0c;但社交关系更多的是停留在表面&#xff0c;无法满足深层次情感交流…