CentOS 编译安装TinyXml2

news2024/11/13 8:13:46

安装

TinyXml2 Git 源码下载地址:https://github.com/leethomason/tinyxml2

步骤1:首先,你需要下载tinyxml2的源代码。你可以从Github或者源代码官方网站下载。并上传至/usr/local/source_code/
 步骤2:下载完成后,需要将源代码解压,可以使用以下命令:

tar -zxvf tinyxml2-8.1.0.tar.gz

步骤3:解压后,切换到源代码目录:

 cd tinyxml2-8.1.0

 步骤4:执行make && make install  命令进行安装:

make &&  make install

温馨提示:完成以上步骤后,在/usr/local/lib下会生成libtinyxml2.so动态库和/usr/local/include下生成tinyxml2.h头文件。你可以使用以下命令查看是否安装成功:

ls /usr/local/lib | grep tinyxml2
ls /usr/local/include | grep tinyxml2

如果看到libtinyxml2.so和tinyxml2.h,则说明成功安装了tinyxml库。

 TinyXml2 库

简介

TinyXML2 是简单实用的开源的 C++XML 文件解析库,可以很方便的应用到现有的项 目之中。 TinyXML2 解析器相对 TinyXML1 在代码上是完全重写,使其更适合于游戏开发 中使用。它使用更少的内存,更快,并使用更少的内存分配。

由于 XML 的树状结构,TinyXML2 将 XML 的节点抽象为 XMLNode,XML 中除了把属 性 key-value 抽象为 XMLAttribute 类型外,其余的都看作 XMLNode 的子类,首先将整个 XML 文档抽象为 XMLDocument,将声明部分抽象为 XMLDeclaration,将注释抽象为 XMLComment,将元素抽象为 XMLElement,将文本抽象为 XMLText。
 

核心:节点、元素、属性和值

XMLAttribute 是解析 XML 的属性的类,XML 中的属性都与 XML 的 Element 绑定,并且为 key-value 类型。

XMLComment       主要是处理 XML 注释的类,注释的存储形式为""。

XMLDeclaration 主要是处理 XML 中声明的类,声明的存储形式为"<? declaration ?>"。 XMLDocument  代表 XML 整个实体,TinyXML2 中只有 XMLDocument 类可以被实例化,其他的类必

须通过 XMLDocument 提供的 new 方法进行实例化,而不能直接实例化。XMLNode

的其他实体类把构造函数定义为 protected,不能被外部实例化,这样保证使用 XMLDocument 进行内存的管理,避免产生内存泄漏的风险。

XMLElement    XMLElement 类是 XMLNode 中最重要的一个类,其存储方式有<foo/>和<foo></foo> 两 种 形 式 , 它 包 含 了 一 个 XMLAttribute 的 根 指 针 , 这 个 root 指 针 指 向 XMLAttribute 的第一个属性键值对。

XMLHandle        主要用来访问元素。

XMLNode     是几乎 XML 所有元素(XMLAttribute 除外)的基类,XML 本质是一种树形结构,而 整个 XML 就是由许多的节点(XMLNode)组成,在 TinyXML2 中每个 XMLNode 节点都 保存了父亲、前驱、后继、孩子头节点和孩子尾节点信息,便于查询、插入、检 索。

XMLPrinter 是 XMLVisitor 类的子类,主要实现的写 XML 的功能,其提供了两种书写方式,一 是构建 XMLDocument,二是直接 push 字段。

XMLText 主要是处理 XML 文本的类,文本信息又分为 CDATA 和普通文本。CDATA 是有专属的 开始字符"<![CDATA[",而普通的文本存储形式如">text<"。

XMLUnknown       存储形式为"<! unknown>"。

XMLVisitor 访问者模式的基类,它主要定义了访问者的接口,而在 XMLNode 的子类的 accept 方法中调用这些方法来完成对自身的访问。
 

示例代码

前提条件:在/usr/local/source_code 创建目录:tinyxml_demmo,并创建tinyXmlDemo.cpp文件,文件内容如下:


#include <iostream>
#include "tinyxml2.h"
#include <stdio.h>
#include <stdlib.h>

using namespace tinyxml2;

/*
enum XMLError {
    XML_SUCCESS = 0,
    XML_NO_ATTRIBUTE,
    XML_WRONG_ATTRIBUTE_TYPE,
    XML_ERROR_FILE_NOT_FOUND,
    XML_ERROR_FILE_COULD_NOT_BE_OPENED,
    XML_ERROR_FILE_READ_ERROR,
    XML_ERROR_PARSING_ELEMENT,
    XML_ERROR_PARSING_ATTRIBUTE,
    XML_ERROR_PARSING_TEXT,
    XML_ERROR_PARSING_CDATA,
    XML_ERROR_PARSING_COMMENT,
    XML_ERROR_PARSING_DECLARATION,
    XML_ERROR_PARSING_UNKNOWN,
    XML_ERROR_EMPTY_DOCUMENT,
    XML_ERROR_MISMATCHED_ELEMENT,
    XML_ERROR_PARSING,
    XML_CAN_NOT_CONVERT_TEXT,
    XML_NO_TEXT_NODE,
        XML_ELEMENT_DEPTH_EXCEEDED,

        XML_ERROR_COUNT
};
*/

//创建XML文件
int createXML(const char* xmlPath)
{
    XMLDocument doc;
    if (XML_ERROR_FILE_NOT_FOUND != doc.LoadFile(xmlPath)) {
        std::cout << "file has been existed !" << std::endl;
        return 0;
    }

    //添加声明 <?xml version="1.0" encoding="UTF-8" ?>
    XMLDeclaration *declaration = doc.NewDeclaration();
    doc.InsertFirstChild(declaration);
    XMLElement *root = doc.NewElement("Users");
    doc.InsertEndChild(root);

    XMLElement *userNode = doc.NewElement("User");
    //添加属性
    userNode->SetAttribute("Name", "milo");
    userNode->SetAttribute("Password", "pwd");
    root->InsertEndChild(userNode);
    return doc.SaveFile(xmlPath);
}

void loadXML(const char* xmlPath) {
    XMLDocument doc;
    if (doc.LoadFile(xmlPath) != XML_SUCCESS) {
        std::cout << "load xlm file failed" << std::endl;
        return;
    }

    XMLPrinter printer;
        doc.Print( &printer);
        std::cout << printer.CStr();
}

//添加性别,号码,邮箱      再添加一个用户
int addXML1(const char* xmlPath) {
    XMLDocument doc;
    if (doc.LoadFile(xmlPath) != XML_SUCCESS) {
        std::cout << "load xlm file failed" << std::endl;
        return -1;
    }

    XMLElement *root = doc.RootElement();

    XMLElement *userNode = root->FirstChildElement("User");
    XMLElement *gender = doc.NewElement("Gender");
    XMLText* genderText = doc.NewText("man");
    gender->InsertFirstChild(genderText);
    userNode->InsertFirstChild(gender);

    XMLElement *mobile = doc.NewElement("Mobile");
    mobile->InsertFirstChild(doc.NewText("186****3143"));
    userNode->InsertEndChild(mobile);

    XMLElement *email = doc.NewElement("Email");
    email->InsertFirstChild(doc.NewText("472251823@qq.com"));
    userNode->InsertEndChild(email);

    XMLElement *userNode2 = doc.NewElement("User");
    userNode2->SetAttribute("Name", "king");
    userNode2->SetAttribute("Password", "pwd2");
    root->InsertEndChild(userNode2);

    XMLElement *mobile2 = doc.NewElement("Mobile");
    mobile2->InsertFirstChild(doc.NewText("186****3143"));
    userNode2->InsertEndChild(mobile2);

    return doc.SaveFile(xmlPath);
}

//在性别后面添加年龄,再添加一个号码
int addXML2(const char* xmlPath)
{
    XMLDocument doc;
    if (doc.LoadFile(xmlPath) != XML_SUCCESS)
    {
        std::cout<<"load xml file failed"<<std::endl;
        return false;
    }

    XMLElement* root=doc.RootElement();
    XMLElement* userNode=root->FirstChildElement("User");
    XMLElement* gender = userNode->FirstChildElement("Gender");
    XMLElement* age = doc.NewElement("Age");

    age->InsertFirstChild(doc.NewText("18"));
    userNode->InsertAfterChild(gender,age);

    XMLElement* mobile = userNode->FirstChildElement("Mobile");
    mobile->SetAttribute("Location","home");

    XMLElement* mobile1 = doc.NewElement("Mobile");
    mobile1->SetAttribute("Location","company");

    mobile1->InsertFirstChild(doc.NewText("186****3143"));
    userNode->InsertAfterChild(mobile, mobile1);

    return doc.SaveFile(xmlPath);
}

//删除第一个号码,删除第二个号码的属性
int deleteXML(const char* xmlPath) {
    XMLDocument doc;
    if (doc.LoadFile(xmlPath) != XML_SUCCESS) {
        std::cout << "load xlm file failed" << std::endl;
        return -1;
    }

    XMLElement *root = doc.RootElement();
    XMLElement *userNode = root->FirstChildElement("User");
    XMLElement *mobile = userNode->FirstChildElement("Mobile");
    userNode->DeleteChild(mobile);
    XMLElement *mobile2 = userNode->FirstChildElement("Mobile");
    mobile2->DeleteAttribute("Location");

    return doc.SaveFile(xmlPath);
}

//将milo的年龄改为10000岁,将king的号码改为8888结尾
int updateXML(const char* xmlPath) {
    XMLDocument doc;
    if (doc.LoadFile(xmlPath) != XML_SUCCESS) {
        std::cout << "load xlm file failed" << std::endl;
        return -1;
    }

    XMLElement *root = doc.RootElement();
    XMLElement *userNode = root->FirstChildElement("User");

    while (userNode != NULL) {
        if (0 == strncmp("milo", (userNode->Attribute("Name")), 11)) {
            userNode->FirstChildElement("Age")->SetText("10000");
            userNode = userNode->NextSiblingElement();
        } else if (0 == strncmp("king", (userNode->Attribute("Name")), 11)) {
            userNode->FirstChildElement("Mobile")->SetText("186****8888");
            userNode = userNode->NextSiblingElement();
        } else {
            userNode = userNode->NextSiblingElement();
        }
    }

    return doc.SaveFile(xmlPath);
}

//将milo的信息打印出来
int selectXML(const char* xmlPath)
{
    XMLDocument doc;
    if(doc.LoadFile(xmlPath)!=XML_SUCCESS)
    {
        std::cout<<"load xml file failed"<<std::endl;
        return false;
    }
    XMLElement* root=doc.RootElement();
    XMLElement* userNode=root->FirstChildElement("User");
    while(userNode != NULL)
    {
        if( 0 == strncmp("milo",(userNode->Attribute("Name")),11))
        {
            std::cout << userNode->Attribute("Name") << std::endl;
            std::cout << userNode->Attribute("Password") << std::endl;
            std::cout << userNode->FirstChildElement("Age")->GetText() << std::endl;
            std::cout << userNode->FirstChildElement("Gender")->GetText() << std::endl;
            std::cout << userNode->FirstChildElement("Mobile")->GetText() << std::endl;
            std::cout << userNode->FirstChildElement("Email")->GetText() << std::endl;
            userNode = userNode->NextSiblingElement();
        } else {
            userNode = userNode->NextSiblingElement();
        }
    }
    return 0;
}

int main( int argc, const char ** argv )
{

    char xmlPath[] = "./0voice.xml";

    /*创建*/
    createXML(xmlPath);
    loadXML(xmlPath);

    printf("------------------------------\n");

    /*增*/
    addXML1(xmlPath);
    loadXML(xmlPath);

    printf("------------------------------\n");

    addXML2(xmlPath);
    loadXML(xmlPath);

    printf("------------------------------\n");

    /*删*/
    deleteXML(xmlPath);
    loadXML(xmlPath);

    printf("------------------------------\n");

    /*改*/
    updateXML(xmlPath);
    loadXML(xmlPath);
    printf("------------------------------\n");

    /*查*/
    selectXML(xmlPath);

    return 0;
}

源码编译,执行如下指令:

g++ tinyXmlDemo.cpp -o tinyXmlDemo -L/usr/local/lib/ -ltinyxml2

执行效果截图:

[root@localhost tinyxml_demmo]# g++ tinyXmlDemo.cpp -o tinyXmlDemo -L/usr/local/lib/ -ltinyxml2
[root@localhost tinyxml_demmo]# ll
总用量 120
-rw-r--r--. 1 root root    168 10月 23 15:36 parseXml.xml
-rwxr-xr-x. 1 root root 110536 10月 23 15:48 tinyXmlDemo
-rw-r--r--. 1 root root   7091 10月 23 15:47 tinyXmlDemo.cpp
[root@localhost tinyxml_demmo]# ./tinyXmlDemo
<?xml version="1.0" encoding="UTF-8"?>
<Users>
    <User Name="milo" Password="pwd"/>
</Users>
------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<Users>
    <User Name="milo" Password="pwd">
        <Gender>man</Gender>
        <Mobile>186****3143</Mobile>
        <Email>472251823@qq.com</Email>
    </User>
    <User Name="king" Password="pwd2">
        <Mobile>186****3143</Mobile>
    </User>
</Users>
------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<Users>
    <User Name="milo" Password="pwd">
        <Gender>man</Gender>
        <Age>18</Age>
        <Mobile Location="home">186****3143</Mobile>
        <Mobile Location="company">186****3143</Mobile>
        <Email>472251823@qq.com</Email>
    </User>
    <User Name="king" Password="pwd2">
        <Mobile>186****3143</Mobile>
    </User>
</Users>
------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<Users>
    <User Name="milo" Password="pwd">
        <Gender>man</Gender>
        <Age>18</Age>
        <Mobile>186****3143</Mobile>
        <Email>472251823@qq.com</Email>
    </User>
    <User Name="king" Password="pwd2">
        <Mobile>186****3143</Mobile>
    </User>
</Users>
------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<Users>
    <User Name="milo" Password="pwd">
        <Gender>man</Gender>
        <Age>10000</Age>
        <Mobile>186****3143</Mobile>
        <Email>472251823@qq.com</Email>
    </User>
    <User Name="king" Password="pwd2">
        <Mobile>186****8888</Mobile>
    </User>
</Users>
------------------------------
milo
pwd
10000
man
186****3143
472251823@qq.com

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LrC 13 ACR 16:点颜色

Adobe Lightroom Classic 13&#xff08; 2023 年 10 月版&#xff09;及 Adobe Camera Raw 16 新增的点颜色 Point Color功能可以方便、精准地调整图像上的颜色。 LrC&#xff1a;修改照片/混色器/点颜色 Develop/Color Mixer/Point Color ACR&#xff1a;编辑/混色器/点颜色 …

希捷推出Exos系列24TB硬盘:配备增强型缓存 性能提高三倍

希捷推出了全新的Exos 24TB硬盘。其基于传统的CMR构建&#xff0c;为3.5英寸规格&#xff0c;转速为7200 RPM。 同时&#xff0c;Exos系列24TB硬盘拥有10片磁盘&#xff0c;每片磁盘的容量为2.4TB&#xff0c;是希捷存储密度最高的硬盘&#xff0c;适用于超大规模企业和数据中心…

最新Jn建站系统2.0 已集成各类源码 【附视频安装教程】

附视频安装教程|已集成各类源码 目前已集成的网站&#xff1a; 1.发卡网(最新) 2.代刷网(无需授权) 3. 博客网(自带模板) 4.易支付(稳定版) 5.个人导航网(简洁) 6.代理查询网 7.留言网 8.匿名网 9.表白墙(最新) 10.抽奖网 11.源码站 12.z-blog博客程序 13.织梦CM…

Ubuntu Linux下如何搭建并安装EDK2

本教程全程手动下载安装&#xff1a; 1、官网下载EDK2安装包(这里下载当前最新版) ---- 2023.10.23 网址&#xff1a;https://sourceforge.net/projects/edk2/files/UDK2015_Releases/UDK2015/UDK2015.Complete.MyWorkSpace.zip 2、解压 unzip UDK2015.Complete.MyWorkSpace…

Android 实现资源国际化(多语言)

目录 一、介绍 二、字符串资源 三、图片资源 四、日期和时间格式 五、其他 六、应用内切换语言 七、资源文件命名规则 一、介绍 Android国际化(多语言)是一种开发技术&#xff0c;旨在使Android应用程序能够在「不同语言和文化环境」下运行&#xff0c;并为用户提供本地…

vue3中使用vue3-pdf-app和使用浏览器内置的PDF插件浏览器PDF文件

文章目录 先准备一个PDF使用浏览器内置的PDF插件预览PDF在HTML中使用浏览器插件预览PDFVscode使用插件发布服务后直接通过URL地址访问PDF可使用的浏览器 在vue3项目中预览PDF文件vue3项目也是可以通过URL地址访问文件的vue3中使用浏览器内置的PDF插件预览PDF代码如下所示&#…

单窗口单IP适合炉石传说游戏么?

游戏道具制作在炉石传说中是一个很有挑战的任务&#xff0c;但与此同时&#xff0c;它也是一个充满机遇的领域。在这篇文章中&#xff0c;我们将向您展示如何在炉石传说游戏中使用动态包机、多窗口IP工具和动态IP进行游戏道具制作。 作者与主题的关系&#xff1a;作为一名热爱炉…

【分布式】大模型分布式训练入门与实践 - 04

大模型分布式训练 数据并行-Distributed Data Parallel1.1 背景1.2 PyTorch DDP1&#xff09; DDP训练流程2&#xff09;DistributedSampler3&#xff09;DataLoader: Parallelizing data loading4&#xff09;Data-parallel&#xff08;DP&#xff09;5&#xff09;DDP原理解析…

nodejs+vue 视频网站的设计与实现

该设计划分为七大模块&#xff0c;包括用户的系统管理、其他管理和视频管理三部分&#xff0c; 和管理管理员的视频、其他管理、系统管理和用户管理四部分。目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关…

【虚幻引擎UE】UE4/UE5 基于2D屏幕坐标获取场景3D坐标 射线检测(蓝图/C++)

UE4/UE5 基于2D屏幕坐标获取场景3D坐标 一、射线检测1&#xff09;定义1&#xff09;射线与3D场景中的物体交互的流程2&#xff09;射线检测蓝图函数3&#xff09;蓝图实现根据鼠标点击位置获取场景中的坐标值4&#xff09;根据相机中心点获取场景中的坐标值5&#xff09;射线检…

迅为RK3588开发板Android12双摄同时显示

要支持双摄同时显示需对源码做如下修改&#xff0c;修改文件 hardware/rockchip/camera/Camera3HALModule.cpp 注释掉下面函数中的部分代码即可。 测试 双摄同时显示需要双摄 app&#xff0c;在网盘资料下载测试 APK&#xff0c;然后使用 adb 安装测试 APK&#xff0c; 启动…

hive窗口函数记录

记录工作中和学习中的窗口函数&#xff0c;方便以后使用&#xff0c;本记持续更新和完善&#xff0c;版本&#xff1a;231019 文章目录 1.什么是窗口函数2.窗口函数的表达式3.窗口函数的类型1&#xff09; 排名函数2&#xff09; 聚合函数3&#xff09; 跨行取值函数 4.[frame…

中英文双语言海外微盘交易源码 微盘交易源码 虚拟币微盘交易系统源码 支持产品数据

Rockefeller微交易源码/双语言海外微盘完整源码/带单控 测试环境&#xff1a;宝塔、Linux、PHP7.3、MySQL5.6 根目录 public&#xff0c;伪静态 larvael5&#xff0c;默认文档&#xff1a;index.html修改为第一个&#xff0c;不然会报404 k线对接的是蜜蜂查&#xff1a;http…

平衡二叉树(AVL)【java实现+图解】

目录 一、平衡二叉树(AVL) 二、平衡二叉树的四种旋转 1.右旋转 2.左旋转 3. 左右旋转 4. 右左旋转 三、基于二叉搜索树之平衡二叉树的代码实现 1.具体方法思路 2.java代码实现 一、平衡二叉树(AVL) 一种自平衡二叉搜索树&#xff0c;它是在每个节点上增加一个平衡因子…

Day 1 Vue 页面框架

现在前端框架越来越像后端了&#xff0c;特别是TypeScript这样的语言出现后&#xff0c;开发前端的体验跟后端渐渐接近了。当然&#xff0c;作为一个后端&#xff0c;直接上手前端&#xff0c;还是有很多坑要填的。 本次开发&#xff0c;前端页面框架直接选择Vue。原因很简单&…

HTML中文本框\单选框\按钮\多选框

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <h1>登录注册</h1> <form action"第一个网页.html" method"post&quo…

字节码进阶之java反射的底层实现原理

文章目录 1. 前言1. 类加载机制2. 字节码操作 2. 反射方法源码分析反射的inflation机制 3. 为什么反射性能差4. 反射的限制与安全性考虑1. **性能开销**2. **安全限制**3. **破坏抽象**4. **版本兼容性问题** 参考文档 java 反射的底层实现原理 1. 前言 Java反射的底层实现原理…

Windows下Eclipse C/C++开发环境配置教程

1.下载安装Eclipse 官网下载eclipse-installer&#xff08;eclipse下载器&#xff09;&#xff0c;或者官方下载对应版本zip。 本文示例&#xff1a; Eclipse IDE for C/C Developers Eclipse Packages | The Eclipse Foundation - home to a global community, the Eclipse ID…

模式识别——高斯分类器

模式识别——高斯分类器 需知定义特殊情况&#xff08;方差一致&#xff09;Sigmoid 需知 所有问题定义在分类问题下&#xff0c;基于贝叶斯决策 定义 条件概率为多元高斯分布&#xff0c;此时观测为向量 X X 1 , X 2 , . . . , X n X{X_1,X_2,...,X_n} XX1​,X2​,...,Xn​…

IP地址在网络安全中的关键作用

IP地址&#xff08;Internet Protocol Address&#xff09;是互联网世界中的重要标识符&#xff0c;它在网络安全领域发挥着至关重要的作用。这些地址不仅帮助设备在网络上找到彼此&#xff0c;还在多个方面有助于维护网络的完整性、机密性和可用性。本文将探讨IP地址在网络安全…