• C++使用TinyXml(开源库)读取*.XMl文件


    xml

    什么是xml?

    目前,对xml的使用非常广泛,读取和设置xml配置文件是我们最常用的操作。常见C/C++ XML解析器有Tinyxml、XERCES、squashxml、xmlite、pugxml、libxml等等,这些解析器有些是支持多语言的,有些只是单纯C/C++的。
    TinyXML是目前非常流行的一款基于DOM模型的XML解析器,简单易用且小巧玲珑,非常适合存储简单数据,配置文件,对象序列化等数据量不是很大的操作。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。

    1. XML 指可扩展标记语言( EX tensible M arkup L anguage)
    2. XML 是一种 标记语言 ,很类似 HTML

    格式示例

    、、 分别为标签,标签内包含了要传递的信息。
    标签必须成对出现,有开始标签就需要有结束标签,例如:
    **开始标签:
    结束标签:
    **

    <Persons>
            <Person ID="1">
                <name>Kobename>
                <age>24age>
            Person>
            <Person ID="2">
                <name>Michaelname>
                <age>23age>
           Person>
     Persons>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    下载TinyXml

    官网下载: https://sourceforge.net/projects/tinyxml/
    csdn : https://download.csdn.net/download/qq_45254369/86266445 (如果没积分可以私聊我发你)
    安装:解压缩tinyXML后,将这六个文件添加到你的C++工程中,分别是tinystr.h、tinystr.cpp、tinyxml.h、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp。在需要操作xml文件的地方,包含tinyxml.h,就可以引入TinyXML类库(#include "tinyxml.h")。

    TinyXml结构

    类名说明
    TiXmlBase整个TinyXML模型的基类。
    TiXmlAttribute对应于XML中的元素的属性。
    TiXmlNode对应于DOM结构中的节点。
    TiXmlComment对应于XML中的注释
    TiXmlDeclaration对应于XML中的申明部分,即<?versiong=“1.0” ?>。
    TiXmlDocument对应于XML的整个文档。
    TiXmlElement对应于XML的元素。
    TiXmlText对应于XML的文字部分
    TiXmlUnknown对应于XML的未知部分。
    TiXmlHandler定义了针对XML的一些操作。

    【实战】读取XMl

    测试的xml文件

    第一行表示版本以及编码格式。
    在这里插入图片描述

    需要建立对应的结构体

    struct Cookbook
    {
    	string name;
    	vector<string> food;
    	vector<string> spices;
    	vector<string> step;
    	void clear()
    	{
    		name.clear();
    		food.clear();
    		spices.clear();
    		step.clear();
    	}
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用到的API

    加载xml文件:
    bool TiXmlDocument::LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
    使用给定的文件名解析加载文件。 如果成功返回true。

    返回根节点
    TiXmlElement* TiXmlDocument::RootElement()

    获取该节点对应的文本
    const TIXML_STRING& TiXmlElement::ValueTStr()

    获取第一个子节点
    const TiXmlElement* FirstChildElement() const;

    获取下一个子节点
    const TiXmlElement* NextSiblingElement() const;

    获取该节点对应的文本
    const char* GetText() const;

    设计一个ParseXML类

    传入一个xml文件路径,就会传出所有的Cookbook。

    class ParseXML
    {
    public:
    	ParseXML();
    	~ParseXML();
    	bool ReadParaXml(string m_strXmlPath, vector<Cookbook>& vecNode);
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    #include "ParseXML.h"
    
    ParseXML::ParseXML() 
    {
    
    }
    
    ParseXML::~ParseXML()
    {
    }
    
    bool ParseXML::ReadParaXml(string m_strXmlPath, vector<Cookbook>& vecNode)
    {
    	Cookbook* pNode = new Cookbook();
    
    	//读取xml文件中的参数值
    	TiXmlDocument* Document = new TiXmlDocument();
    	if (!Document->LoadFile(m_strXmlPath.c_str()))
    	{
    		cout << "无法加载xml文件!" << endl;
    		cin.get();
    		return false;
    	}
    	TiXmlElement* RootElement = Document->RootElement();		//根目录
    
    	TiXmlElement* NextElement = RootElement;		//根目录下的第一个节点层
    	while (NextElement != NULL)		//判断有没有读完
    	{
    		if (NextElement->ValueTStr() == "menu")		//读到menu节点
    		{
    			TiXmlElement* BoxElement = NextElement->FirstChildElement();
    			while (BoxElement->ValueTStr() != "name")		//读到name节点
    			{
    				BoxElement = BoxElement->NextSiblingElement();
    
    			}
    			pNode->name = BoxElement->GetText(); 
    			BoxElement = BoxElement->NextSiblingElement();
    
    			
    			while (BoxElement->ValueTStr() == "food")		// 读到food节点
    			{
    				pNode->food.push_back(BoxElement->GetText());
    				BoxElement = BoxElement->NextSiblingElement();
    			}
    			while (BoxElement->ValueTStr() == "spices")		// 读到spices节点
    			{
    				pNode->spices.push_back(BoxElement->GetText());
    				BoxElement = BoxElement->NextSiblingElement();
    			}
    			while (BoxElement != nullptr && BoxElement->ValueTStr() == "step")// 读到step节点
    			{
    				pNode->step.push_back(BoxElement->GetText());
    				BoxElement = BoxElement->NextSiblingElement();
    			}
    			vecNode.push_back(*pNode);
    			pNode->clear();
    			
    		}
    		NextElement = NextElement->NextSiblingElement();
    	}
    
    	//释放内存
    	delete pNode;
    	delete Document;
    	cout << "完成xml的读取" << endl;
    	return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    测试结果

    因为我这个是QT做的ui界面,这里只需要关注内容是否对应即可。
    在这里插入图片描述

  • 相关阅读:
    c#——switch case语句
    RecycleView的一些使用
    【问题复盘】在Ubuntu 20.04下安装OFED驱动
    JS逆向实战19——通杀webpack逆向
    js-构造函数方法的重复创建--解决
    二分图 二分图最大匹配
    PaddleOCR学习笔记2-初步识别服务
    MongoDB数据库
    求所有质因子(Java)
    UIView Animation 动画学习总结
  • 原文地址:https://blog.csdn.net/qq_45254369/article/details/126065569