c/c++操作xml库-Tinyxml2入门及高级用法

一、概念

TinyXML2是一个开源、简单、小巧、高效的C++ XML解析器,它只有一个.h文件和一个.cpp文件组成,可以轻松集成到其它程序中。它解析XML文档并从中构建可以读取、修改和保存的文档对象模型(Document Object Model, DOM)。它不能解析DTD(Document Type Definitions, 文档类型定义)或XSL(eXtensible Stylesheet Language, 扩展样式表语言)。在TinyXML2中,XML数据被解析为可以浏览和操作的C++对象,然后写入磁盘和其它输出流。它不依赖于C++的STL。

TinyXML2的license为ZLib,可以商用,它的源码在https://github.com/leethomason/tinyxml2 ,最新发布版本为7.1.0。

基本类型

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

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

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

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

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

XMLElement XMLElement 类是 XMLNode 中最重要的一个类,其存储方式有和 两 种 形 式 , 它 包 含 了 一 个 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 方法中调用这些方法来完成对自身的访问。
在这里插入图片描述

————————————————
版权声明:本文为CSDN博主「jenie」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jenie/article/details/106729883

二、引入

在include中放入tinyxml2.h
在source中放入tinyxml2.cpp

#include "tinyxml2.h"
using namespace tinyxml2;

三、加载

方法一 加载文件

#define TEST_PATH "/tmp/test.xml";

XMLDocument doc; 
if (doc.LoadFile(TEST_PATH ) != XMLError::XML_SUCCESS) {
    std::cout << "load xlm file failed" << std::endl;
    return;
}

方法二 创建空文档


const string XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

XMLDocument doc; 
doc.Parse(XML_HEADER.data());

四、基本操作

1、创建新节点

# 新增根节点
XMLElement* config = doc.NewElement( "config" );
doc.InsertEndChild( config );

# 新增下级节点
XMLElement* e = doc.RootElement()->FirstChildElement("node1");
// 可以替换为
// XMLElement* e = config ->FirstChildElement("node1");
if(e == NULL){
    e = doc.NewElement( "node1" );
    doc.RootElement()->InsertEndChild( e  );
    // 或者
    // config->InsertEndChild( e  );
}

2、查询节点

XMLElement* e = doc.RootElement()->FirstChildElement("node1");

3、 遍历每个节点

for (XMLElement* currentele = doc.RootElement()->FirstChildElement(); currentele; currentele = currentele->NextSiblingElement())
{
	const char* name = currentele->Name();
    
}

4、 获取节点名称

const char* name = e->Name();

5、 删除节点

doc.RootElement()->DeleteChild(e);

6、 添加text

XMLText* value = doc.NewText("OFFLINE");
e->InsertEndChild(value);

7、 获取text

const char* text = e->GetText();
int64_t intValue= p->FirstChildElement("ExposureTime")->Int64Text();
bool flag= p->FirstChildElement("TriggerMode")->BoolText();

8、修改text值

e->SetText("vlue")

9、查找属性

const char*name,*value;
const XMLAttribute *valueAttr = e->FirstAttribute();
if (valueAttr != NULL){
	name = e->Name();
    value = valueAttr->Value();
    int port = atoi(valueAttr->Value());
    this->web_port = port;
    LOG_INFO("指定了web端口:%d",port);
}

// 查找指定属性
const XMLAttribute *valueAttr = e->FirstAttribute("value");

10、获取属性值

/*
const char *tinyxml2::XMLElement::Attribute(const char *name, const char *value = (const char *)0) const
Given an attribute name, Attribute() returns the value
for the attribute of that name, or null if none
exists. For example:

@verbatim
const char* value = ele->Attribute( "foo" );
@endverbatim

The 'value' parameter is normally null. However, if specified,
the attribute will only be returned if the 'name' and 'value'
match. This allow you to write code:

@verbatim
if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
@endverbatim

rather than:
@verbatim
if ( ele->Attribute( "foo" ) ) {
if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
}
@endverbatim
*/
const char* value = e->Attribute("Name")

判断属性值是否一致

if ( ele->Attribute( "foo", "bar" ) ) doSomething();

也可以这样写

if ( ele->Attribute( "foo" ) ) {
	if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) doSomething();
}

11、 设置属性

e->SetAttribute("value", metadataUrl.data());

e->SetAttribute("type", "home");
e->SetAttribute("price", 1000);
e->SetAttribute("wifi", true);

12、删除属性

e->DeleteAttribute("value");

13、 保存文件

// 保存到文件
int result=doc.SaveFile(TEST_PATH );
sync();

14、 获取xml字符串

XMLPrinter printer;
doc.RootElement()->Accept( &printer );
string xmltext = printer.CStr();

char *temp = (char *)malloc(xmltext.length()+1); 
strcpy(temp,xmltext.data());  //间接赋值
*(event->body) = temp;  

参考:https://blog.csdn.net/fengbingchun/article/details/99689509

  • 4
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值