RapidXml读取并修改XML文件

article/2025/9/13 8:39:22

RapidXml读取并修改XML文件

  • RapidXml介绍
  • RapidXml读取与修改xml文件

RapidXml介绍

     RapidXml尝试创建最快的XML解析器,同时保留可用性,可移植性和合理的W3C兼容性。它是一个用现代C ++编写的原位解析器,解析速度接近strlen在同一数据上执行的函数。它仅仅只由四个头文件组成,并不要单独进行配置编译,使用起来非常方便。
在RapidXml的官网上,它发布了与其他xml解析库的速度对比,应该可以说RapidXml是目前最快的xml解析器。
在这里插入图片描述
RapidXml通过使用以下几种技术实现了它的速度:
1,原位解析。构建DOM树时,RapidXml不会复制字符串数据,例如节点名称和值。相反,它存储指向源文本内部的指针。
2,使用模板元编程技术。这允许它将大部分工作转移到编译时。通过模板的魔力,C ++编译器为您使用的任何解析器标志组合生成解析代码的单独副本。在每个副本中,所有可能的决定都在编译时进行,并且省略所有未使用的代码。
3,广泛使用查找表进行解析。
4,手动调优的C ++,在几个最流行的CPU上进行了分析。

RapidXml读取与修改xml文件

     我们以下面这个xml为例,找到key值为"ReportIndex"的节点,并在这个节点前面插入一个新的节点"",同时将key值为"ReportIndex"的节点以及后面的节点的offset值都加上4。

<hsbinmsg limit_size="5096" note="hsbinmsg msgtype info"><head note="packet head"><field key="msgtype" type="6" offset="0"/><field key="bodylength" type="6" offset="4"/></head><tail note="packet tail"><field key="checksum" type="6" offset="-1"/></tail><msgtype id="202098" name="DesignationReport(202098)"><dataset note=""><field key="ReportIndex" type="7" offset="12" size="8"/><field key="app1id" type="17" offset="20" size="3"/></dataset></msgtype>
</hsbinmsg>

     CXmlParse解析类的头文件如下:

#pragma once
#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
#include "rapidxml_print.hpp"
#include <string>#define XML_NODE_NAME  "msgtype"
#define XML_NODE_NAME2 "ReportIndex"#define OFFSET_SIZE		4class CXmlParse
{
public:CXmlParse(const std::string &strPath);~CXmlParse();private:int LoadXml();//找到key为name的属性bool GetAttrByName(const char* name, rapidxml::xml_node<>* pNode, rapidxml::xml_attribute<> *&pAttr);void UpdateAtributeValue(rapidxml::xml_document<> &doc, rapidxml::xml_attribute<>* &pAttr, int nOffset);void MakeFileCopy(const std::string& strPath);private:std::string m_strPath;std::string m_strNewPath;
};

     cpp实现文件:

#include "XmlParse.h"
#include <windows.h>
#include <iostream>CXmlParse::CXmlParse(const std::string &strPath)
{m_strPath = strPath;MakeFileCopy(m_strPath);if (LoadXml()){std::cout << "XML处理成功" << std::endl;}else{std::cout << "XML处理失败" << std::endl;}
}CXmlParse::~CXmlParse()
{}//加载xml
int CXmlParse::LoadXml()
{if (m_strPath.empty()){return -1;}try{rapidxml::file<> file(m_strPath.c_str());rapidxml::xml_document<> doc;doc.parse<0>(file.data());//根节点rapidxml::xml_node<>* root = doc.first_node();rapidxml::xml_node<>* pNode = root->first_node();while (pNode)	//第二层节点head,msgtype{std::string strName = pNode->name();if (strName.compare(XML_NODE_NAME) == 0)   //找到msgtype{rapidxml::xml_node<>* pNode2 = pNode->first_node();	//第三层节点datasetif (pNode2){rapidxml::xml_node<>* pNode3 = pNode2->first_node();	//第四层节点field,只找第一个bool bFind = false;rapidxml::xml_attribute<> *attr;if (GetAttrByName("key", pNode3, attr)){if (strcmp(attr->value(), "ReportIndex") == 0){bFind = true;}}if (bFind){//遍历第四层节点field节点, offset偏移量+4while (pNode3){rapidxml::xml_attribute<> *attrSize;GetAttrByName("offset", pNode3, attrSize);UpdateAtributeValue(doc, attrSize, OFFSET_SIZE);pNode3 = pNode3->next_sibling();}//只要找到了一个key="ReportIndex"的field,那么就需要新插入一个noderapidxml::xml_node<> *pNewNode = doc.allocate_node(rapidxml::node_element, "field");if (pNewNode){pNewNode->append_attribute(doc.allocate_attribute("key", "PartitionNo"));pNewNode->append_attribute(doc.allocate_attribute("type", "6"));pNewNode->append_attribute(doc.allocate_attribute("offset", "8"));pNewNode->append_attribute(doc.allocate_attribute("size", "4"));pNode2->prepend_node(pNewNode);}}}}pNode = pNode->next_sibling();}std::ofstream out(m_strNewPath);out << doc;out.close();	return 1;}catch (...){std::cout << "XML解析出现异常" << std::endl;return -1;}
}//获取到节点中key为name的属性
bool CXmlParse::GetAttrByName(const char* name, rapidxml::xml_node<>* pNode, rapidxml::xml_attribute<> *&pAttr)
{if (pNode == NULL)return false;for (rapidxml::xml_attribute<> *attr = pNode->first_attribute(); attr; attr = attr->next_attribute()){if (strcmp(attr->name(), name) == 0){pAttr = attr;return true;}}return true;
}//更新属性的值
void CXmlParse::UpdateAtributeValue(rapidxml::xml_document<> &doc, rapidxml::xml_attribute<>* &pAttr, int nOffset)
{if (NULL == pAttr)return;const char* oldValue = pAttr->value();int nValue = atoi(oldValue);nValue += nOffset;char str[12];memset(str, 0, 12);_itoa_s(nValue, str, 10);pAttr->value(doc.allocate_string(str), strlen(str));
}//根据原路径得到新路径(原路径名+“2”)
void CXmlParse::MakeFileCopy(const std::string& strPath)
{std::string strNewPath = strPath;int nPos = strNewPath.find_last_of(".");if (nPos != std::string::npos){std::string strTemp = strNewPath.substr(nPos + 1);strNewPath = strNewPath.substr(0, nPos);strNewPath += "2.";strNewPath += strTemp;m_strNewPath = strNewPath;}
}

     RapidXml遍历节点跟TinyXml遍历节点的方式一样,都是先获取根节点,然后获取到根节点下方的first_node(),然后通过next_sibling()不停地指向下一个兄弟节点,同时兄弟节点也可以深度去遍历。获取节点的各个属性值也是一样的使用方式。
     本程序为了和原xml文件作对比,就创建了新的文件,如果想在原文件上做修改,直接将std::ofstream out(m_strNewPath);中的m_strNewPath替换为m_strPath即可。
类封装好后,调用也非常方便。

CXmlParse parse(strPath);

     附上完整例子代码:Demo


http://chatgpt.dhexx.cn/article/eZvvfZwC.shtml

相关文章

c++开源库rapidxml介绍与示例

官方地址&#xff1a;http://rapidxml.sourceforge.net/ 官方手册&#xff1a;http://rapidxml.sourceforge.net/manual.html 也可以在github上下载到别人上传的rapidxml:https://github.com/dwd/rapidxml 1.头文件 一般我们用到的头文件只有这三个 #include "rapidx…

Ubuntu 18.04 LDAP认证

将ubuntu配置为通过ldap认证&#xff0c;使其成为ldap client&#xff0c;系统版本ubuntu 18.04。 一 软件安装 apt-get install ldap-utils libpam-ldap libnss-ldap nslcd配置1 配置2 配置3 配置4 配置5 配置6 配置7 配置8 配置8 二 认证方式中添加Ldap #auth-client-conf…

LDAP认证服务器

1.要准备的环境与软件(这里测试环境是Centos6.0-64位系统) alfresco-community-4.2.c-installer-linux-x64.bin (注: alfresco是一个免费开源系统&#xff0c;可以自己去下载) apache-tomcat-7.0.42.tar db-4.5.20.tar jdk-6u45-linux-x64.bin openldap-stable-20100219.tar ph…

Jumpserver部署+Ldap认证

内容导航 &#xff08;一&#xff09;jumpserver快速部署1&#xff0c;部署内容2&#xff0c;附上安装脚本3&#xff0c;解决github无法连接4&#xff0c;修改配置 &#xff08;二&#xff09;使用jumpserver1&#xff0c;登录信息2&#xff0c;添加主机3&#xff0c;web终端登…

SVN使用LDAP认证

前言 SVN架构 用户访问SVN服务器分为两个部分&#xff1a;认证与授权。 SVN内置了有认证与授权机制&#xff0c;其认证是通过SVN仓库内的passwd文件提供&#xff0c;但它是明文、静态的&#xff0c;不方便且安全性低。 SVN还支持外部的认证&#xff0c;比如SASL&#xff0c;…

ldap 认证 java_Java实现LDAP认证(上)

Baidu脑残&#xff0c;把原来的空间改得不伦不类。所以把一些技术的东西挪到这里。 我找到两种方法&#xff0c;大同小异&#xff0c;第一种是通过Spring&#xff0c;适合已经采用Spring的项目。 一般来说用户名和密码都是保存在数据库中。现在有这个需求&#xff0c;用户名和密…

Harbor 整合ldap认证

前提&#xff1a; ldap服务器已经安装&#xff1a;OpenLDAP安装部署 harbor服务器已经安装&#xff1a;Harbro v1.8.0部署 一、ldap组织结构 1、登录信息 2、查看用户信息 二、harbor配置 1、使用默认密码登录&#xff0c;admin/Harbor12345 2、认证模式 3、测试ldap服务器…

ldap认证 java_Java实现LDAP认证(上) | 学步园

Baidu脑残&#xff0c;把原来的空间改得不伦不类。所以把一些技术的东西挪到这里。 我找到两种方法&#xff0c;大同小异&#xff0c;第一种是通过Spring&#xff0c;适合已经采用Spring的项目。 一般来说用户名和密码都是保存在数据库中。现在有这个需求&#xff0c;用户名和密…

Zabbix 整合ldap认证

前提&#xff1a; zabbix部署完成&#xff1a;CentOS7.3 64位&#xff0c;搭建Zabbix3.4 ldap部署完成&#xff1a;OpenLDAP安装部署 一、LDAP服务端 1、ldap登录信息 2、查看ldap组织架构 3、添加zabbix默认用户Admin 二、Zabbix网页端 1、使用zabbix默认管理员用户登录 …

linux+配置ldap认证,Linux LDAP 认证配置

Linux通过LDAP方式&#xff0c;使用windows AD帐户登录linux shell&#xff0c;这个想法很cool吧。之前配置过一次&#xff0c;但过了太久忘记了&#xff0c;因此&#xff0c;今天把配 Linux通过LDAP方式&#xff0c;使用windows AD帐户登录linux shell&#xff0c;这个想法很c…

JumpServer 整合ldap认证

前提&#xff1a; ldap服务器已经安装&#xff1a;OpenLDAP安装部署 一、JumpServer安装 官网安装地址安装部署 - JumpServer 文档 1、一键部署 #系统版本 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) #默认会安装到 /opt/jumpser…

linux samba 配置ldap认证,Samba集成Ldap认证

Samba集成Ldap认证 1.基础安装 yum -y install samba-common samba samba-client smbldap-tools openldap-clients nss-pam-ldapd 2.配置authconfig-tui 执行命令 "authconfig-tui" 验证配置 # getent passwd zhangsan:x:6460:18650:zhangsan:/home/zhangsan:/bin/…

SVN集成LDAP认证

如何将 LDAP 的认证&#xff0c;集成到 SVN 中。集成的办法&#xff0c;目前是有两种&#xff1a;一种是 SVN 直接通过 SVN 端口直接访问的&#xff0c;通过 SASL 实现 LDAP 的认证&#xff1b;另一种是 SVN 通过 Apache 进行 HTTP 访问的用户&#xff0c;通过配置 Apache &…

zabbix配置ldap认证

zabbix配置ldap认证 环境&#xff1a; centos6.6 zabbix3.0.3 域控服务器&#xff1a;windows-active server 2008 需求&#xff1a; 公司越来越大&#xff0c;人越来越多&#xff0c;配置人员的账号密码很麻烦。 为了集中管理&#xff0c;整合公司的用户密码&#xff0c…

LDAP认证-ldap介绍

OpenLDAP简介 LDAP 全称轻量级目录访问协议&#xff0c;是一个运行在 TCP/IP 上的目录访问协议。LDAP实现 提供被称为目录服务的信息服务&#xff0c;可以看做是一张特殊的数据库系统。可以有效的 解决众多网络服务的用户账户问题&#xff0c;规定了统一的身份信息数据库、身份…

LDAP认证

注&#xff1a;本文由网络公开资料整理而来&#xff0c;如有错误&#xff0c;欢迎指正。 LDAP&#xff08;Lightweight Directory Access Protocol&#xff09;是目录服务&#xff08;DAP&#xff09;在TCP/IP上的实现&#xff0c;它是对X.500目录协议的移植&#xff0c;但是简…

BlazeDS简单介绍

BlazeDS 是一个基于服务器的 Java 远程控制 (remoting) 和 Web 消息传递 (messaging) 技术&#xff0c;以LGPL&#xff08;Lesser GNU Public License&#xff09;公共许可证书发布。它能够使得后端的 Java 应用程序和运行在浏览器上的 Adobe Flex 应用程序相互通信。在Java应用…

关于BLAS的简单介绍

BLAS(Basic Linear Algebra Subprograms基础线性代数程序集)是进行向量和矩阵等基本线性代数操作的事实上的数值库。这些程序最早在1979年发布&#xff0c;是LAPACK(Linear Algebra PACKage)的一部分&#xff0c;便于建立功能更强的数值程序包。BLAS库在高性能计算中被广泛应用…

Blazor 基础入门

Blazor 基础知识 Intro Blazor 是微软在 .NET 里推出的一个 WEB 客户端 UI 交互的框架&#xff0c; 使用 Blazor 你可以代替 JavaScript 来实现自己的页面交互逻辑&#xff0c;可以很大程度上进行 C# 代码的复用&#xff0c;Blazor 对于 .NET 开发人员来说是一个不错的选择。 托…

Blazeds学习

BlazeDS是一个基于服务器的Java远程调用&#xff08;remoting&#xff09;和Web消息传递&#xff08;messaging&#xff09;技术&#xff0c;使得后台的Java应用程序和运行在浏览器上的Flex应用程序能够相互通信 一个BlazeDS应用包括两个部分&#xff1a;一个客户端应用程序和…