C++解析xml示例

C++解析xml示例

  • 1. Xml文档介绍
    • 1.1 特点及作用
    • 1.2 Xml优点
      • 1.2.1 良好的可拓展性
      • 1.2.2 内容与形式分离
    • 1.3 Xml组成
      • 1.3.1 Xml声明
      • 1.3.2 根元素
      • 1.3.3 元素
      • 1.3.4 属性
      • 1.3.5 实体
      • 1.3.6 注释
  • 2 C++解析Xml
    • 2.1 tinyXml2类库
    • 2.2 关键接口
      • 2.2.1 LoadFile
      • 2.2.2 RootElement
      • 2.2.3 FirstChildElement
      • 2.2.4 NextSiblingElement
      • 2.2.5 Value
      • 2.2.6 Attribute
      • 2.2.7 ToDeclaration
  • 3 搜索Xml中数据案例

1. Xml文档介绍

Xml(Extensible Markup Language)即可扩展标记语言,Xml是互联网数据传输的重要工具,它可以跨越互联网任何的平台,不受编程语言和操作系统的限制,可以说它是一个拥有互联网最高级别通行证的数据携带者。

Xml用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。Xml是标准通用标记语言(SGML)的子集,非常适合Web传输。Xml提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

在很多工具或服务中需要解析Xml,此文档供相关开发人员使用C++解析Xml做参考。

1.1 特点及作用

Xml特点:

  1. xml与操作系统、编程语言的开发平台都无关;
  2. 实现不同系统之间的数据交互;
    Xml作用:
  3. 配置应用程序和网站,在配置文件里几乎所有的配置文件都是以Xml的格式来编写的;
  4. 数据交互,即服务器以XML的形式传输数据;
  5. 储存数据;

1.2 Xml优点

1.2.1 良好的可拓展性

在XML产生之前,要想定义一个置标语言并推广利用它非常困难。一方面,如果制定了一个新的语言而期望它能生效,需要把这个标准提交给相关的组织(如W3C),等待它接受并正式公布这个标准,经过几轮的评定和修改,到这个置标语言终于成为一个正式推荐标准时,可能已经过了几年的时间。另一方面,为了让这套标记得到广泛应用,制订者必须为它配备浏览工具。这样,就不得不去游说各个浏览器厂商接受并支持新制定的标记,或者索性自己开发一个新的浏览器去与现有的浏览器竞争,无论哪个办法,都需要耗费大量的时间和工作。现在借助XML的帮助,制定新的置标语言要简单易行得多了,这也正是XML的优势所在。

各个不同的行业可能会有一些独特的要求,比如说,化学家需要化学公式中的一些特殊符号,建筑家需要设计图纸中的某些特殊的标记,音乐家需要音符,这些都需要单独的标记。但是,其他网页设计者一般不会用这些记号,也不需要这些标记。XML的优点就在于它允许各个组织、个人建立适合他们自己需要的标记库,并且这个标记库可以迅速地投入使用。

1.2.2 内容与形式分离

XML不仅允许自定义一套标记,而且这些标记不必仅限于对显示格式的描述。在XML中,显示样式从数据文档中分离出来,放在样式单文件中。这样,如果要改动信息的表现方式,无须改动信息本身,只要改动样式单文件就够了。如果这时候把列表的数据改用表格显示,无须再去修改大量数据信息文档,因为它们和同一个样式文件相关联,只要改动这个样式单文件就可以了。

在XML中数据搜索可以简单高效地进行。 若在HTML文件中搜索某个字符串,脚本会逐字寻找对应的字符串,即使找到了,若存在多个相同目标字符串,也不能确定是否为自己想要找到的那个。在XML中搜索不必要再去遍历整个文档,只需要找一下相关标记下的内容。此外,信息之间的某些复杂关系,比如树状结构、继承关系等,在XML中也都得到了绝好的体现,这样就大大方便了XML的应用处理程序的开发。

1.3 Xml组成

一个正规的Xml文档的结构需要有声明,文档元素描述信息(有且仅有一个根元素),元素属性。也可能包含实体,注释等信息。
在这里插入图片描述

1.3.1 Xml声明

在编写XML文档时,需要先使用文档声明来声明XML文档。且必须出现在文档的第一行。最简单的声明语法:

<?xml version="xxx"?>

Version后引号内的字符串表示文档的版本。

当我们写好的一个xml文件写入内存的时候会转换为二进制保存,这个时候会查码表,记事本保存的时候是gbk,而保存的时候默认查码表时用的是utf-8,这个时候我们就可以用encoding属性:默认是UTF-8

<?xml version="xxx” encoding="GBK"?>

这样就可以解决乱码等问题。

Xml声明还可能包含standlone属性:该xml文件是否独立存在。

1.3.2 根元素

根元素是Xml文档里面唯一的,它的开始是放在最前面,结束是放在最后面。
在这里插入图片描述

1.3.3 元素

根元素下的所有元素格式与根元素相同,其格式为:
在这里插入图片描述
Note

  1. 所有元素都必须有开始标签和结束标签;
  2. 开始标签和结束标签的名称必须相同(区分大小写);
  3. 元素title名称可以包含字母,数字或者其他字符,但是不能以数字或者符号开头,名称中不能包含空格;
  4. 名称字符之间不能使用冒号(有特殊用途);

1.3.4 属性

对于有属性的元素,语法结构为:

<元素名 属性名=“属性值”></元素名>

Note

  1. 属性值用双引号包括,一个元素可以有多个属性;
  2. 属性值中不能直接包含符号;

1.3.5 实体

在xml中,一些字符拥有特殊的意义。如果把字符“<”放在xml元素中,会发生错误,这是因为解析器会把它当作新元素的开始,这样会产生xml错误。

为了避免这个错误,在元素中需要引用这些字符时,用实体引用来代替字符。Xml中5个预定义实体:

实体符号
&It;<
>>
&&
"*
'.

1.3.6 注释

注释语法:
<!—注释内容–>
Note:

  1. 注释内容中不要出现“–”;
  2. 注释不能嵌套;
  3. XML声明之前不能有注释,不允许第一行写注释;

2 C++解析Xml

2.1 tinyXml2类库

在C++中读写Xml会用到一个C++库tinyXml2类库。这个库中包含了我们读取Xml所需的接口。

TinyXML2是一个开源、简单、小巧、高效的C++ XML解析器,可以轻松集成到其它程序中。目前存在两个著名的开源XML文件解析库:tinyXml1,tinyXml2。相对tinyXml1而言,tinyXml2更为简洁,它只有一个tinyXml2.h文件和一个tinyXml2.cpp文件组成,而tinyXml1包含了6个文件。

TinyXml2具有以下几个优点:

  1. 对大部分的C/C++项目具有普适性,并且拥有丰富的测试案例;
  2. 使用较少的内存(约 TinyXML1 的 40%),速度变得更快;
  3. 没有C++的STL要求;
  4. 更接近现代 C++ 的特性,如使用了适当的命名空间;
  5. 适当有效的处理了的空白字符(空格,Tab 和回车);

使用方法:将 tinyxml2.cpp 和 tinyxml2.h 拷贝至项目目录,使用时包含头文件和引入名字空间。

2.2 关键接口

2.2.1 LoadFile

作用:用于加载Xml文件

在这里插入图片描述

传参:LoadFile(FilePath)

一般使用格式:

if(Xml.LoadFile(FilePath)!=XML_SUCCESS)// 通过Xml文件路径读取文件,若读取失败则返回
	return;

2.2.2 RootElement

作用:用于读取Xml的根节点

在这里插入图片描述

传参:RootElement()

一般使用格式:

tinyxml2::XMLElement* rootElement = NULL;
rootElement=Xml.RootElement();//rootElement指向当前Xml的根节点
if(rootElement==NULL)//若读取失败则返回
return;

2.2.3 FirstChildElement

作用:用于读取xml节点的下一层节点
在这里插入图片描述
传参:(1)FirstChildElement()//读取下一层节点的第一个节点
(2)FirstChildElement(“XXX”)//读取下一层节点第一个元素名为“XXX”的节点

一般使用格式:

const XMLNode* Element1 = NULL;
Element1 = rootElement-> FirstChildElement(“XXX”);//Element1指向rootElement的下一层第一个元素名为”XXX”的节点
if(Element1 ==NULL)//若读取失败则返回
return;

2.2.4 NextSiblingElement

作用:用于读取Xml节点同层节点的下一个节点

在这里插入图片描述

传参:NextSiblingElement()

一般使用格式:

const XMLNode* Element2 = NULL;
Element2 = Element1 -> NextSiblingElement ();//Element2指向Element1的同层节点的下一个节点
if(Element2 ==NULL)//若读取失败则返回
return;

2.2.5 Value

作用:用于读取Xml节点的元素名

在这里插入图片描述

传参:Value()

一般使用格式:

String str1= Element2->Value();//将Element2的元素名赋值给str1

2.2.6 Attribute

作用:用于读取Xml节点的属性值

在这里插入图片描述
传参:Attribute()

一般使用格式:

String str2 = Element2->ToElement()->Attribute(“XXX”);//将Element2的属性名为”XXX”的属性值赋值给str2

2.2.7 ToDeclaration

作用:用于读取Xml文件的声明

在这里插入图片描述

传参:ToDeclaration()

一般使用格式:

tinyxml2::XMLDocument xmlParse;
if (xmlParse.LoadFile(str_xmlPath.c_str()) != tinyxml2::XML_SUCCESS)
	return -1;
XMLNode *decl= xmlParse.FirstChild();
if(NULL!= decl)
	{
	XMLDeclaration* declaration =decl->ToDeclaration();
string strDecl = declaration->Value();//最终将声明字符串赋值给strDecl
}

3 搜索Xml中数据案例

通常在Xml中搜索数据会有很多限制条件,需要通过层层搜索找到想要的数据。
在这里插入图片描述
如图中,若希望通过限制条件WwanDeviceConfigID-ID,FCC_MAP_INDEX_TYPE- Value,Standard- Vaule,Item- PSensors/ DeviceMode/ AntMode/ AntMode1找到对应的Item –SarIndex,代码案例如下,是一个对应的从Xml中搜索数据的接口(代码部分,仅供参考):

int CStateWork::GetSarIndexFromXml(string str_xmlPath, string WwanDeviceConfigID, string regmcc, string PSensors, string DeviceMode, string AntMode, string AntMode1)
	string SarIndex;
do
	{
1.初始化
		tinyxml2::XMLDocument xmlParse;
		tinyxml2::XMLElement* rootElement = NULL;
		const XMLNode* WwanDeviceConfigIDElement = NULL;
		const XMLNode* WwanDeviceConfigIDList = NULL;
		const XMLNode* FCC_MAP_INDEX_TYPE_Element = NULL;
		const XMLNode* MapTypeElement = NULL;
		const XMLNode* StandardElement = NULL;
		const XMLNode* ItemElement = NULL;
		string FCC_MAP_INDEX_TYPE;
int i_ret = -1;
2.加载Xml文件,并获取根节点
		if (xmlParse.LoadFile(str_xmlPath.c_str()) != tinyxml2::XML_SUCCESS)
		{
			return i_ret;
		}
		rootElement = xmlParse.RootElement();
		if (NULL == rootElement)
		{
			return i_ret;
		}
3.通过传参WwanDeviceConfigID,找到对应的WwanDeviceConfigID节点
		WwanDeviceConfigIDList = rootElement->FirstChildElement("WwanDeviceConfigIDList");
		if (NULL == WwanDeviceConfigIDList)
		{
			return i_ret;
		}
		WwanDeviceConfigIDElement = WwanDeviceConfigIDList->FirstChildElement("WwanDeviceConfigID");
		for (WwanDeviceConfigIDElement; WwanDeviceConfigIDElement; WwanDeviceConfigIDElement = WwanDeviceConfigIDElement->NextSiblingElement())
		{
			if (WwanDeviceConfigIDElement->ToElement()->Attribute("ID") == WwanDeviceConfigID)
				break;
		}

4.在WwanDeviceConfigID节点下,找到FCC_MAP_INDEX_TYPE节点的属性值
		FCC_MAP_INDEX_TYPE_Element = WwanDeviceConfigIDElement->FirstChildElement("FCC_MAP_INDEX_TYPE");
		if (NULL == FCC_MAP_INDEX_TYPE_Element)
		{
			return i_ret;
		}
		FCC_MAP_INDEX_TYPE = FCC_MAP_INDEX_TYPE_Element->ToElement()->Attribute("Value");

5.在WwanDeviceConfigID节点下,找到与FCC_MAP_INDEX_TYPE节点的属性值对应的MapType

		MapTypeElement = WwanDeviceConfigIDElement->FirstChildElement(FCC_MAP_INDEX_TYPE.c_str());
		if (NULL == MapTypeElement)
		{
			return i_ret;
		}

6.在MapType节点下,找到属性值与传参regmcc对应的Standard节点
		StandardElement = MapTypeElement->FirstChildElement("Standard");
		if (NULL == StandardElement)
		{
			return i_ret;
		}
		for (StandardElement; StandardElement; StandardElement = StandardElement->NextSiblingElement())
		{
			if (StandardElement->ToElement()->Attribute("Vaule") == regmcc)
				break;
		}

7.在Standard节点下,找到属性值与传参PSensors,DeviceMode,AntMode,AntMode1一一对应的Item节点(不同的MapType属性个数不同,需要先判断在哪个MapType下搜索)
		ItemElement = StandardElement->FirstChildElement("Item");
		if (NULL == ItemElement)
		{
			return i_ret;
		}
		if (FCC_MAP_INDEX_TYPE.find("MapType_1") != std::string::npos)
		{
			ItemElement = StandardElement->FirstChildElement();
			if (NULL == ItemElement)
			{
				return i_ret;
			}
		}
		else if (FCC_MAP_INDEX_TYPE.find("MapType_2") != std::string::npos)
		{
			if (PSensors == "")

			{
				return i_ret;
			}
			ItemElement = StandardElement->FirstChildElement();
			if (NULL == ItemElement)
			{
				return i_ret;
			}
			while (ItemElement->ToElement()->Attribute("PSensors") != PSensors)
			{
				ItemElement = ItemElement->NextSiblingElement();
				if (NULL == ItemElement)
				{
					return i_ret;
				}
			}
		}
		else if (FCC_MAP_INDEX_TYPE.find("MapType_3") != std::string::npos)
		{
			if (DeviceMode == "")
			{
				return i_ret;
			}
			ItemElement = StandardElement->FirstChildElement();
			if (NULL == ItemElement)
			{
				return i_ret;
			}
			while (ItemElement->ToElement()->Attribute("DeviceMode") != DeviceMode)
			{
				ItemElement = ItemElement->NextSiblingElement();
				if (NULL == ItemElement)
				{
					return i_ret;
				}
			}
		}
		else if (FCC_MAP_INDEX_TYPE.find("MapType_4") != std::string::npos)
		{
			if (PSensors == "")
			{
				return i_ret;
			}
			if (DeviceMode == "")
			{
				return i_ret;
			}
			ItemElement = StandardElement->FirstChildElement();
			if (NULL == ItemElement)
			{
				return i_ret;
			}
			while (ItemElement->ToElement()->Attribute("PSensors") != PSensors
				|| ItemElement->ToElement()->Attribute("DeviceMode") != DeviceMode)
			{
				ItemElement = ItemElement->NextSiblingElement();
				if (NULL == ItemElement)
				{
					return i_ret;
				}
			}
		}
		else if (FCC_MAP_INDEX_TYPE.find("MapType_5") != std::string::npos)
		{
			if (PSensors == "")
			{
				return i_ret;
			}
			if (AntMode == "")
			{	
				return i_ret;
			}
			if (AntMode1 == "")
			{
				return i_ret;
			}
			ItemElement = StandardElement->FirstChildElement();
			if (NULL == ItemElement)
			{
				return i_ret;
			}
			while (ItemElement->ToElement()->Attribute("PSensors") != PSensors
				|| ItemElement->ToElement()->Attribute("AntMode") != AntMode
				|| ItemElement->ToElement()->Attribute("AntMode1") != AntMode1)
			{
				ItemElement = ItemElement->NextSiblingElement();
				if (NULL == ItemElement)
				{
					return i_ret;
				}
			}
		}
		else if (FCC_MAP_INDEX_TYPE.find("MapType_6") != std::string::npos)
		{
			if (PSensors == "")
			{
				return i_ret;
			}
			if (AntMode == "")
			{
				return i_ret;
			}
			if (AntMode1 == "")
			{
				return i_ret;
			}
			if (DeviceMode == "")
			{
				return i_ret;
			}
			ItemElement = StandardElement->FirstChildElement();
			if (NULL == ItemElement)
			{
				return i_ret;
			}
			while (ItemElement->ToElement()->Attribute("PSensors") != PSensors
				|| ItemElement->ToElement()->Attribute("AntMode") != AntMode
				|| ItemElement->ToElement()->Attribute("AntMode1") != AntMode1
				|| ItemElement->ToElement()->Attribute("DeviceMode") != DeviceMode)
			{
				ItemElement = ItemElement->NextSiblingElement();
				if (NULL == ItemElement)
				{
					return i_ret;
				}
			}
		}

8.在Item节点下,读出SarIndex属性值,并作为最终接口的输出
		SarIndex = ItemElement->ToElement()->Attribute("SarIndex");
	} while (FALSE);
	return atoi(SarIndex.c_str());
}

Note:

  1. 在LoadFile Xml文件时,应该判断是否成功打开,若失败则返回;
  2. 在获取任何新的节点以及节点指向的位置变动后,应该判断当前节点是否为空,若为空则应该返回或做其他异常处理;
  3. 当前节点往下向子节点搜寻,一般直接用FirstChild函数直接实现,当前节点往下向同级节点搜寻,一般用NextSiblingElement函数遍历实现;
  4. 在同一个元素中可能会有多组属性和属性值,在这种情况下搜索相应的数据一般需要用循环,对于每一次循环都是获取一次新的节点,因此在循环前和每一次循环后都应该判断当前节点是否为空,以免出现crash

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

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

相关文章

计算机网络扫盲(2)——网络边缘

一、概述 在计算机网络得到术语中&#xff0c;我们把与因特网相连的计算机或其他设备称为端系统&#xff08;或者主机&#xff09;&#xff0c;如下图所示&#xff0c;因为它们位于因特网的边缘&#xff0c;所以被称为端系统。因特网的端系统包括了桌面计算机&#xff…

Linux的权限(一)

目录 权限的本质 Linux权限的概念 如何创建与删除普通用户 创建普通用户&#xff1a; 设置用户密码&#xff1a; 删除普通用户&#xff1a; 删除与该用户关联的主目录和邮件目录 &#xff1a; su指令 sudo指令 Linux权限管理 Linux中文件访问者有三种“人” Linux…

HashMap源码全面解析

注&#xff1a;本篇文章是在JDK1.8版本源码进行分析。 一、概述 HashMap 是基于哈希表的 Map接口的实现&#xff0c;是以 key-value 存储形式存在&#xff0c;即主要用来存储键值对。 HashMap的类图&#xff1a; HashMap继承抽象类AbstractMap&#xff0c;实现了Map、Clonea…

深度学习:什么是知识蒸馏(Knowledge Distillation)

1 概况 1.1 定义 知识蒸馏&#xff08;Knowledge Distillation&#xff09;是一种深度学习技术&#xff0c;旨在将一个复杂模型&#xff08;通常称为“教师模型”&#xff09;的知识转移到一个更简单、更小的模型&#xff08;称为“学生模型”&#xff09;中。这一技术由Hint…

基于SpringBoot蜗牛兼职网的设计与实现

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;蜗牛兼职网当然也不能排除在外。蜗牛兼职网是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c…

面试就是这么简单,offer拿到手软(一)—— 常见非技术问题回答思路

面试系列&#xff1a; 面试就是这么简单&#xff0c;offer拿到手软&#xff08;一&#xff09;—— 常见非技术问题回答思路 面试就是这么简单&#xff0c;offer拿到手软&#xff08;二&#xff09;—— 常见65道非技术面试问题 文章目录 一、前言二、常见面试问题回答思路问…

算法通关村第四关—栈的经典算法问题(白银)

emsp;emsp;栈的经典算法问题 一、括号匹配问题 emsp;首先看题目要求&#xff0c;LeetCode20.给定一个只包括’(‘&#xff0c;)’&#xff0c;‘{&#xff0c;’&#xff0c;[&#xff0c;]的字符串s&#xff0c;,判断字符串是否有效。有效字符串需满足&#xff1a; 1.左括号…

python绘制箱线图boxplot——用于多组数据的比较, 异常值检测

python绘制箱线图boxplot——用于多组数据的比较, 异常值检测 介绍箱线图方法简介箱线图适用范围seaborn.boxplot箱图外观设置异常值marker形状、填充色、轮廓设置完整代码 如下matplotlib.pyplot常见参数介绍 本文系统详解利用python中seaborn.boxplot绘制箱图boxplot。seab…

Linux系统安装Docker-根据官方教程教程(以Ubuntu为例)

Linux系统安装Docker-根据官方教程教程&#xff08;以Ubuntu为例&#xff09; 1. 背景介绍2. 环境配置2.1 软件环境要求2.2 软件下载2.3 文档地址2.3 必备命令工具下载 3. 安装Docker3.1 使用root用户操作后续命令3.2 卸载可能存在的旧版本 4. 安装Docker4.1 更新依赖包4.2 配置…

npm ERR! notarget No matching version found for @eslint/eslintrc@^2.1.4.

文章目录 Intro解决流程总结前置信息了解npm 镜像源三个要用到的npm命令 官方源确认查看当前镜像源的详情解决&#xff1a; 切换镜像源后重试重新操作 事后感受 Intro 事由是今天我在用 create-react-app 新建一个用于测试的前端项目。 然后就出现以下报错&#xff1a; wuyuj…

RHCSA学习笔记(RHEL8) - Part2.RH134

Chapter Ⅰ 提高命令行生产率 SHELL脚本 #/bin/bash声明使用的shell翻译器 for循环 for VAR in LIST doCOMMAND1COMMAND2 done实验1&#xff1a;显示host1-5 #! /bin/bash for host in host{1..5} doecho $host done实验2&#xff1a;显示包含kernel的软件包安装时间 #! /…

【鸿蒙应用ArkTS开发系列】-自定义底部菜单列表弹窗

文章目录 前言创建Demo工程创建dialog 文件夹创建ListMenu 接口创建自定义弹窗 ListMenuDialog使用自定义弹窗 打包测试效果演示默认效果菜单带图标效果设置文本颜色效果不同文本颜色效果无标题效果 前言 上一篇文章中我们实现了选择图片、选择文件、拍照的功能 。 链接在这里…

【网络协议】聊聊网络ReadTimeout和ConnectTimeout

在实际的开发中&#xff0c;网络超时是一个比较常见的问题&#xff0c;比如说针对支付系统&#xff0c;超时就需要进行和三方人员进行核对订单状态&#xff0c;是否人工介入处理。 但其实在设计网络框架的时候&#xff0c;一般都有两个超时参数 连接超时参数 ConnectTimeout&am…

阻抗匹配电阻原理及其应用

一、匹配电阻的作用 1、阻抗匹配 当信号频率比较高&#xff0c;上升沿比较陡时&#xff0c;电子信号经过阻抗不同的地方时也会产设反射。 PCB的单线阻抗一般会设计成50Ω&#xff0c;发射端阻抗一般是17到40&#xff0c;而接收端一般是MOS管的输入&#xff0c;阻抗是比较大的…

Python 高性能 web 框架 - FastApi 全面指南

原文&#xff1a;Python 高性能 web 框架 - FastApi 全面指南 - 知乎 一、简介 FastAPI 是一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的 web 框架&#xff0c;使用 Python 3.6 并基于标准的 Python 类型提示。 它具有如下这些优点&#xff1a; 快速&…

shell编程系列(11)-使用grep查找文本

文章目录 前言grep的使用根据关键字查找反向查找 结语 前言 grep命令也是我们在日常使用linux&#xff0c;编写shell脚本中会用到的一个高频命令&#xff0c;grep主要是帮助我们查找我们想要的内容&#xff0c;类似于我们在office word里面的 Ctrl f 查找功能&#xff0c;但是…

LabVIEW在不同操作系统上使VI、可执行文件或安装程序

LabVIEW在不同操作系统上使VI、可执行文件或安装程序 LabVIEW可以在多个操作系统上运行&#xff0c;主要支持以下几种操作系统&#xff1a; Windows&#xff1a; LabVIEW在各个版本的Windows操作系统上都能运行&#xff0c;包括Windows 7、Windows 8和Windows10。LabVIEW为Wi…

docker容器中创建非root用户

简介 用 docker 也有一段时间了&#xff0c;一直在 docker 容器中使用 root 用户肆意操作。直到部署 stable diffusion webui 我才发现无法使用 root 用户运行它&#xff0c;于是才幡然醒悟&#xff1a;是时候搞个非 root 用户了。 我使用的 docker 镜像文件是 centos:centos…

使用系统ProgressBar实现三色进度条

使用系统ProgressBar实现如图三色进度条&#xff1a; //布局中<ProgressBarandroid:layout_width"0dp"android:layout_height"8dp"android:layout_marginLeft"16dp"app:layout_constraintBottom_toBottomOf"id/photo"app:layout_c…

解决报错:error: (-215:Assertion failed) inv_scale_x > 0 in function ‘cv::resize‘

需求背景 欲使用opencv的resize函数将图像沿着纵轴放大一倍&#xff0c;即原来的图像大小为(384, 512), 现在需要将图像放大为(768, 512)。 源码 import cv2 import numpy as np# 生成初始图像 img np.zeros((384, 512), dtypenp.uint8) img[172:212, 32:-32] 255 H, W …