【XML】TinyXML 详解(二):接口详解

news2025/1/16 15:50:41

【C++】郭老二博文之:C++目录

1、XML测试文件(laoer.xml)

<?xml version="1.0" standalone="no" ?>
<!-- Hello World !-->
<root>
    <child name="childName" id="1">
        <c_child name="c_child1Name" id="1">Text</c_child>
        <c_child name="c_child2Name" id="2">Text</c_child>
        <c_child name="c_child3Name" id="3">Text</c_child>
	</child>
    <child name="childName" id="2">Text</child>
    <child name="childName" id="3">
        <c_child name="c_child1Name" id="1">Text</c_child>
        <c_child name="c_child2Name" id="2">Text</c_child>
        <c_child name="c_child3Name" id="3">Text</c_child>
        <c_child name="c_child4Name" id="4">Text</c_child>
        <c_child name="c_child5Name" id="5">Text</c_child>
        <c_child name="c_child6Name" id="6">Text</c_child>
	</child>
    <child1 name="child1Name" id="4">Text</child1>
    <child2 name="child1Name" id="5">Text</child1>
    <child3 name="child1Name" id="6">Text</child1>
</root>

2、读取文件并打印

加载xml文件:TiXmlDocument::LoadFile()
获取错误信息:TiXmlDocument::ErrorDesc()
打印XML内容:TiXmlDocument::Print( stdout )

#include <iostream>
#include <sstream>

#include "tinyxml.h"

using namespace std;

int main()
{
    TiXmlDocument doc( "laoer.xml" );
    bool loadOkay = doc.LoadFile();

    if ( !loadOkay )
    {
        printf( "Could not load file 'gw.xml'. Error='%s'. Exiting.\n", doc.ErrorDesc() );
        exit( 1 );
    }

    doc.Print( stdout );
}

4、属性相关接口

4.1 获取属性

获取属性有四类接口

  • Attribute :获取属性,如果返回空,则表示不存在
  • QueryStringAttribute:获取属性,返回值“错误检查”值
  • C++ STL(使用std::string)
  • C++模版接口

1)Attribute 原型如:

const char* Attribute( const char* name ) const;
const char* Attribute( const char* name, int* i ) const;
const char* Attribute( const char* name, double* d ) const;
……

2)QueryStringAttribute 原型如:

int QueryIntAttribute( const char* name, int* _value ) const;
int QueryDoubleAttribute( const char* name, double* _value ) const;
……

3)C++ STL(使用std::string) 原型如:

const std::string* Attribute( const std::string& name ) const;
const std::string* Attribute( const std::string& name, int* i ) const;
const std::string* Attribute( const std::string& name, double* d ) const;

int QueryIntAttribute( const std::string& name, int* _value ) const;
int QueryDoubleAttribute( const std::string& name, double* _value ) const;
……

4)C++模版接口 原型如:

template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const

4.2 设置属性

1)SetAttribute 原型如:

void SetAttribute( const char* name, const char * _value );
void SetAttribute( const char * name, int value );

2)SetDoubleAttribute 原型如:
void SetDoubleAttribute( const char * name, double value );

3)C++STL(使用std::string) 原型如:

void SetAttribute( const std::string& name, const std::string& _value );
void SetAttribute( const std::string& name, int _value );
void SetDoubleAttribute( const std::string& name, double value );
void printNameID(const TiXmlElement * const element)
{
    std::string name;
    if (element->QueryStringAttribute( "name", &name ) != TIXML_SUCCESS)
    {
        std::cout << "[ERR] QueryStringAttribute " << std::endl;
    }

    int id = -1;
    if (!element->Attribute("id", (int*)&id))
    {
        std::cout << "[ERR] Attribute(id " << std::endl;
    }

    std::cout << "name = " << name <<"; id = " <<id << std::endl;
}

4.3 删除属性

void RemoveAttribute( const char * name );
void RemoveAttribute( const std::string& name )

5、遍历子元素

1)返回第一个子元素:TiXmlElement* TiXmlNode::FirstChildElement()
2)返回第一个匹配“value”的子元素:TiXmlElement* TiXmlElement* FirstChildElement( const std::string& _value )
3)返回下一个兄弟元素:TiXmlElement* NextSiblingElement()
4)返回下一个匹配“value”的兄弟元素:TiXmlElement* NextSiblingElement( const std::string& _value)

#include <iostream>
#include <sstream>

#include "tinyxml.h"

using namespace std;

int main()
{
    TiXmlDocument doc( "laoer.xml" );
    TiXmlNode* rootNode = 0;
    TiXmlElement* rootElement = 0;
    
    rootNode = doc.FirstChild( "root" );
    rootElement = rootNode->ToElement();
    
    for( childElement = rootElement->FirstChildElement("child");
         childElement;
         childElement = childElement->NextSiblingElement("child") )
    {
        printNameID(childElement);
    }
}

6、TiXmlHandle 类

6.1 检查空指针

TiXmlHandle主要用来检测空节点指针(null)的类。
注意:TiXmlHandle 不是DOM 元素树的一部分,类关系如下
在这里插入图片描述

例如,遍历如下XML文档:

<Document>
	<Element attributeA = "valueA">
		<Child attributeB = "value1" />
		<Child attributeB = "value2" />
	</Element>
<Document>

TiXmlElement每次获取子元素后,都需要检查是否为NULL,否则操作NULL空指针将会报错

TiXmlElement* root = document.FirstChildElement( "Document" );
if ( root )
{
	TiXmlElement* element = root->FirstChildElement( "Element" );
	if ( element )
	{
		TiXmlElement* child = element->FirstChildElement( "Child" );
		if ( child )
		{
			TiXmlElement* child2 = child->NextSiblingElement( "Child" );
			if ( child2 )
			{
				// Finally do something useful.

使用 TiXmlHandle 可以简化上面的操作

TiXmlHandle docHandle( &document );
TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
if ( child2 )
{
	// do something useful

6.2 遍历元素

下面使用while循环遍历元素,看上去很合理,其实Child方法内部是一个线性遍历来查找元素,即下面的示例是两个嵌入的while循环

int i=0; 
while ( true ){
	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
	if ( !child )
		break;
		// do something
		++i;
	}

代替方法:

TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();

for( child; child; child=child->NextSiblingElement("Child") )
{
	// do something
}

注意上面 NextSiblingElement(“Child”) 和 NextSiblingElement()的区别

6.3 常用接口

TiXmlHandle FirstChild() const;//返回第一个子节点的句柄:
TiXmlHandle FirstChild( const std::string& _value ) const; //返回给定名称的第一个子节点的句柄。
TiXmlHandle FirstChildElement() const;//返回第一个子元素的句柄。
TiXmlHandle FirstChildElement( const std::string& _value ) const;//返回给定名称的第一个子元素的句柄。
TiXmlHandle Child( int index ) const;//返回指定索引“index”子节点的句柄。
TiXmlHandle Child( const std::string& _value, int index ) const;//返回给定名称指定索引“index”子节点的句柄。
TiXmlHandle ChildElement( int index ) const;//返回指定索引“index”子元素的句柄。
TiXmlHandle ChildElement( const std::string& _value, int index ) const//返回给定名称指定索引“index”子元素的句柄。

获取节点、元素、文本、未知元素的接口
TiXmlNode* ToNode() const
TiXmlElement* ToElement() const
TiXmlText* ToText() const
TiXmlUnknown* ToUnknown() const

7、创建XML

1)TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
在“最后子节点”后添加新节点。如果发生错误则返回NULL。(addThis)是const引用,在内部会被复制addThis.Clone()

2)TiXmlNode* LinkEndChild( TiXmlNode* addThis );
在“最后子节点”后添加新节点,这里addThis 是指针,将被作为链表的一个项,插入到链表中,因此它内存管理将有父节点TiXmlNode接管。

3)TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
在指定子节点之前添加子节点。

4)TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
在指定的子元素之后添加子元素。

5)TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
替换指定的节点

6)bool RemoveChild( TiXmlNode* removeThis );
删除指定的节点

#include <iostream>
#include <sstream>

#include "tinyxml.h"

using namespace std;

int main()
{
    TiXmlDocument doc( "laoer.xml" );
    TiXmlNode* rootNode = 0;
    TiXmlElement* rootElement = 0;

	// 创建新节点 "child3"
    TiXmlElement child( "child3" );
    child.SetAttribute( "name", "child3" );
    child.SetAttribute( "id", "8" );
	
	// 创建节点文本
    TiXmlText text( "text" );
	
	// 创建孙子节点1
    TiXmlElement c_child1( "c_child" );
    c_child1.SetAttribute( "name", "c_child1" );
    c_child1.SetAttribute( "id", "1" );
	
	// 创建孙子节点2
    TiXmlElement c_child2( "c_child" );
    c_child2.SetAttribute( "name", "c_child2" );
    c_child2.SetAttribute( "id", "2" );
	
	// 组装子节点
    child.InsertEndChild( text );
    child.InsertEndChild( c_child1 );
    child.InsertEndChild( c_child2 );
	
	// 获取插入点位置,将新节点插入到指定位置
    childElement = rootElement->FirstChildElement("child2");
    rootElement->InsertAfterChild( childElement, child );
    
    doc.Print( stdout );
    doc.SaveFile();
}

修改后的XML如下,请自行和博文开头的做对比

<?xml version="1.0" standalone="no" ?>
<!-- Hello World !-->
<root>
    <child name="childName" id="1">
        <c_child name="c_child1Name" id="1">Text</c_child>
        <c_child name="c_child2Name" id="2">Text</c_child>
        <c_child name="c_child3Name" id="3">Text</c_child>
    </child>
    <child name="childName" id="2">Text</child>
    <child name="childName" id="3">
        <c_child name="c_child1Name" id="1">Text</c_child>
        <c_child name="c_child2Name" id="2">Text</c_child>
        <c_child name="c_child3Name" id="3">Text</c_child>
        <c_child name="c_child4Name" id="4">Text</c_child>
        <c_child name="c_child5Name" id="5">Text</c_child>
        <c_child name="c_child6Name" id="6">Text</c_child>
    </child>
    <child1 name="child1Name" id="4">Text</child1>
    <child2 name="child1Name" id="5">Text</child2>
    <child3 name="child3" id="8">text
        <c_child name="c_child1" id="1" />
        <c_child name="c_child2" id="2" />
    </child3>
    <child3 name="child1Name" id="6">Text</child3>
</root>

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

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

相关文章

基于docker-compose 安装Sonar并集成gitlab

文章目录 1. 前置条件2. 编写docker-compose-sonar.yml文件3. 集成 gitlab4. Sonar Login with GitLab 1. 前置条件 安装docker-compose 安装docker 创建容器运行的特有网络 创建挂载目录 2. 编写docker-compose-sonar.yml文件 version: "3" services:sonar-postgre…

如何更好地理解和掌握 KMP 算法?

KMP算法是一种字符串匹配算法&#xff0c;可以在 O(nm) 的时间复杂度内实现两个字符串的匹配。本文将引导您学习KMP算法&#xff0c;阅读大约需要30分钟。 1、字符串匹配问题 所谓字符串匹配&#xff0c;是这样一种问题&#xff1a;“字符串 P 是否为字符串 S 的子串&#xf…

Python入门学习篇(六)——for循环while循环

1 for循环 1.1 常规for循环 1.1.1 语法结构 for 变量名 in 可迭代对象:# 遍历对象时执行的代码 else:# 当for循环全部正常运行完(没有报错和执行break)后执行的代码1.1.2 示例代码 print("----->学生检查系统<------") student_lists["张三",&qu…

TensorRT-Alpha FAQ

1、linux下出现错误&#xff1a; libyolov8.so: undefined reference to sample::splitToStringVec(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char) collect2: error: ld returned 1 exit status CMa…

FPC柔性线路板使用UV胶水的优势有哪些?

UV胶水在FPC柔性线路板的装配中具有明显的优势&#xff1a; 快速固化 UV胶水在紫外线照射后10秒左右迅速固化&#xff0c;因此它能够在短时间内完成连接。这非常有助于实际工业作业中提高生产效率&#xff0c;特别是在需要大批量生产的情况下。 精确控制固化时间 UV胶水的固…

考研往应届考生报名流程?

文章目录&#xff1a; 一&#xff1a;考试时间相关 二&#xff1a;公告查询获取信息 三&#xff1a;提供材料 1.基本要求 2.证件要求 四&#xff1a;相关问题 1.报名流程如何操作 2.考点选择 2.1 应届考生考点选择 2.2 往届考生考点选择 3.预报名时间可能不同 4.档…

QT编写应用的界面自适应分辨率的解决方案

博主在工作机上完成QT软件开发&#xff08;控件大小与字体大小比例正常&#xff09;&#xff0c;部署到客户机后&#xff0c;发现控件大小与字体大小比例失调&#xff0c;具体表现为控件装不下字体&#xff0c;即字体显示不全&#xff0c;推测是软件不能自适应分辨率导致的。 文…

Windows系统找不到xinput1_3.dll怎么办?

引言&#xff1a; 在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是xinput1_3.dll丢失。那么&#xff0c;xinput1_3.dll究竟是什么&#xff1f;为什么会出现丢失的情况&#xff1f;丢失后会对计算机产生什么影响&#xff1f;本文将详细介绍…

阿里面试官:面试了一个能力相当不错的候选人,但背调时,他前同事和领导都说他人品很差,纠结该不该要他?...

* 你好&#xff0c;我是前端队长&#xff0c;在职场&#xff0c;玩副业&#xff0c;文末有福利! 在职场中&#xff0c;背调是个躲不开的事情。不管是各行各业背调可能都存在&#xff0c;只是形式不同而已。而且现在大环境不好&#xff0c;可能对个人的要求还更高一些。 背调的主…

以存算一体芯片加速汽车智能化进程,后摩智能带来更优解?

汽车产业的长期价值锚点已悄然变化&#xff0c;催生出新的商业机遇。 过去&#xff0c;在燃油车市场&#xff0c;燃油经济性和品牌认知度等是重要的消费决策因素和资本价值衡量标准&#xff0c;但在新能源时代&#xff0c;产业价值聚焦在两方面&#xff0c;一是电动化&#xf…

生物信息学R分析工具包ggkegg的详细使用方法

ggkegg介绍 ggkegg 是一个用于生物信息学研究的工具&#xff0c;可以用于分析和解释基因组学数据&#xff0c;并将其与已知的KEGG数据库进行比较。ggkegg 是从 KEGG 获取信息并使用 ggplot2 和 ggraph 进行解析、分析和可视化的工具包&#xff0c;结合其他使用 KEGG 进行生物功…

ansible的脚本:playbook剧本

&#xff08;一&#xff09;playbook的组成部分 tasks 任务&#xff0c;包含要在主机上执行的操作&#xff0c;使用模块定义这些操作&#xff0c;每一个任务都是一个模块的调用 variables 变量&#xff0c;存储和传递数据&#xff08;和shell脚本中的变量是一个意思&#xf…

Python通过telnet批量管理配置华为交换机

名称&#xff1a;Python通过telnet批量管理配置华为交换机 测试工具&#xff1a;ensp, Visual Studio Code &#xff0c; Python3.8环境 时间&#xff1a;2023.12.23 个人备注&#xff1a;在NB 项目中&#xff0c;可以批量登录修改交换机配置&#xff0c;以此满足甲方爸爸的…

echarts:设置折线图线条和端点的颜色

1、代码 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>Echarts折线图</title> </head> <body> <div id"main" style"width: 600px;height:400px;"></div> <sc…

《成才之路》期刊投稿方式发表论文要求

《成才之路》杂志是国家新闻出版署批准的正规教育类G4期刊&#xff0c;是国家新闻出版署权威认定专业学术期刊。本刊密切关注人才教育与培养的理论和实践&#xff0c;关注人才学研究的前沿问题&#xff0c;特别是各学科教育教学一线的育才新理念、育才新方法、育才新思路&#…

表达式求值的优先级,结合性及隐式类型转化

文章目录 前言一&#xff0c;操作符的属性二、1&#xff0c;表达式求值的优先级1&#xff0c;什么是优先级2&#xff0c;表达式的优先级表格 三、表达式的结合性1&#xff0c;什么是表达式的结合性2&#xff0c;表达式的结合性表格 四&#xff0c;隐式类型转换1&#xff0c;什么…

032 - STM32学习笔记 - TIM基本定时器(一) - 定时器基本知识

032 - STM32学习笔记 - TIM定时器&#xff08;一&#xff09; - 基本定时器知识 这节开始学习一下TIM定时器功能&#xff0c;从字面意思上理解&#xff0c;定时器的基本功能就是用来定时&#xff0c;与定时器相结合&#xff0c;可以实现一些周期性的数据发送、采集等功能&#…

[JS设计模式]Mixin Pattern

Mixin是一个对象&#xff0c;我们可以使用它来为另一个对象或类添加可重用的功能&#xff0c;而无需使用继承。我们不能单独使用mixins:它们的唯一目的是在没有继承的情况下向对象或类添加功能。 假设对于我们的应用程序&#xff0c;我们需要创建多个狗。然而&#xff0c;我们…

JavaWeb笔记之JSP

一、引言 现有问题 在之前学习Servlet时&#xff0c;服务端通过Servlet响应客户端页面&#xff0c;有什么不足之处&#xff1f; 开发方式麻烦&#xff1a;继承父类、覆盖方法、配置Web.xml或注解。 代码修改麻烦&#xff1a;重新编译、部署、重启服务。 显示方式麻烦&#x…

Linux创建macvlan 测试bridge、private和vepa模式

Linux创建macvlan&#xff0c;测试bridge、private和vepa模式 最近在看Docker的网络&#xff0c;看到关于macvlan网络的介绍。查阅了相关资料&#xff0c;记录如下。 参考 1.Linux Macvlan 2.图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN 环境 操…