Windows下编译TinyXML(XML文件解析)

作者:翟天保Steven

版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

TinyXML是什么?

TinyXML是一个轻量级的C++ XML解析器,它提供了一种简单的方法来解析和操作XML文档。TinyXML被设计为易于使用和集成到C++项目中,并且非常适合处理小型XML文件。

以下是TinyXML的一些主要特点和优点:

  1. 轻量级: TinyXML的设计目标之一是保持代码库的小巧简洁,因此它非常适合用于嵌入式系统或具有资源限制的环境。

  2. 简单易用: TinyXML提供了简单直观的API,使得解析和操作XML文档变得容易。它的API设计使得开发人员可以快速上手并完成XML处理任务。

  3. 跨平台性: TinyXML是跨平台的,可以在各种操作系统上运行,包括Windows、Linux和Mac OS等。

  4. 开源: TinyXML是开源的,可以在许可证允许的情况下免费使用和修改。

  5. 支持XML解析和生成: TinyXML支持解析XML文档,并且可以将XML数据写入到文件或内存中。

  6. 适用于小型XML文件: 尽管TinyXML可以解析和处理XML文件,但它更适用于处理小型XML文件,因为它的设计目标之一是保持简洁和高效。

虽然TinyXML功能不如一些更复杂的XML库,但它的简单性和轻量级使得它成为处理小型XML任务的良好选择。

下载与编译

1)网站:TinyXML download | SourceForge.net,下载TinyXML压缩包。

我下载了一版,百度云地址:

链接:https://pan.baidu.com/s/1ZF1GPuFiv_BJK8RIsmVMgw
提取码:dvfe

2)把这六个文件拿出来就可以用了。两个h,四个cpp。

3)按我的习惯,我调用第三方库喜欢用动态库或静态库而不是源码,如果你不需要编译库,就不用往下看了。压缩包里提供了sln项目文件,打开可以编译,但是我试了一下发现只能编译32位。因此,打开VS重新创建一个空项目TinyXML。把那几个文件拖过来,并在项目中添加现有项。

4)项目属性,改为lib,编译静态库。

​ 5)点击生成解决方案,提示成功即可。

​ 6)创建一个文件夹,把头文件和lib放进去,库就编译好了。

配置与测试

​ 1)配置头文件路径。

​ 2)配置lib路径。

​​ 3)链接lib。

​​ 4)测试代码+测试xml文件(自己创建一个xml就可以了)+测试效果。

cpp 复制代码
#include <algorithm>
#include <chrono>
#include <ctime>
#include <direct.h>
#include <functional>
#include <fstream>
#include <iostream>
#include <io.h>
#include <map>
#include <numeric>
#include <omp.h>
#include <random>
#include <regex>
#include <stdio.h>
#include <sstream>
#include <string>
#include <set>
#include <time.h>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <Windows.h>
#include <tinyxml.h>

using namespace std;

// Structure to hold node data
struct NodeData 
{
	std::string name;
	std::unordered_map<std::string, std::string> attributes;
	std::vector<NodeData> children;
	std::string text;
};

// Function to parse attributes from an XML node
std::unordered_map<std::string, std::string> parseAttributes(const TiXmlElement* theNode) {
	std::unordered_map<std::string, std::string> attributes;

	const TiXmlAttribute* attribute = theNode->FirstAttribute();
	while (attribute) 
    {
		std::string attrName = attribute->Name();
		std::string attrValue = attribute->Value();
		attributes[attrName] = attrValue;
		attribute = attribute->Next();
	}

	return attributes;
}

// Function to parse child nodes
void parseChildNodes(const TiXmlNode* theNode, NodeData& nodeData) {
	if (!theNode->FirstChild()) // Check if the node has child nodes
		return;

	const TiXmlNode* child = theNode->FirstChild();
	while (child) 
    {
		if (child->Type() == TiXmlNode::TINYXML_ELEMENT) 
        {
			const TiXmlElement* element = child->ToElement();
			NodeData childNodeData;
			childNodeData.name = element->Value();
			childNodeData.attributes = parseAttributes(element);
			parseChildNodes(child, childNodeData);
			nodeData.children.push_back(childNodeData);
		}
		else if (child->Type() == TiXmlNode::TINYXML_TEXT) 
        {
			const char* text = child->ToText()->Value();
			if (text) 
            {
				std::string textContent = text;
				textContent.erase(textContent.find_last_not_of(" \n\r\t") + 1); // Trim trailing whitespaces
				if (!textContent.empty()) 
                {
					nodeData.text = textContent;
				}
			}
		}
		child = child->NextSibling();
	}
}

// Function to display node data recursively
void displayNodeData(const NodeData& node, int depth = 0) 
{
	// Display current node
	cout << string(depth * 4, ' ') << "Name: " << node.name << endl;
	cout << string(depth * 4, ' ') << "Attributes:" << endl;
	for (const auto& attr : node.attributes) 
    {
		cout << string(depth * 4, ' ') << "  " << attr.first << " : " << attr.second << endl;
	}
	if (!node.text.empty()) 
    {
		cout << string(depth * 4, ' ') << "Text: " << node.text << endl;
	}

	// Display child nodes recursively
	for (const auto& child : node.children) 
    {
		displayNodeData(child, depth + 1);
	}
}

int main()
{
	TiXmlDocument doc("test.xml");
	if (!doc.LoadFile()) 
    {
		std::cerr << "Failed to load XML file!" << std::endl;
		return 1;
	}

	const TiXmlElement* root = doc.RootElement();
	if (!root) 
    {
		std::cerr << "Root element not found!" << std::endl;
		return 1;
	}

	// Create structure to hold root node data
	NodeData rootNodeData;
	rootNodeData.name = root->Value();
	rootNodeData.attributes = parseAttributes(root);

	// Parse child nodes
	parseChildNodes(root, rootNodeData);

	// Display all node data
	displayNodeData(rootNodeData);

	cout << "end." << endl;
	return 0;
}
cpp 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <person>
        <name>John Doe</name>
        <age>30</age>
        <city>New York</city>
    </person>
    <person>
        <name>Jane Smith</name>
        <age>25</age>
        <city>Los Angeles</city>
    </person>
</root>

以上就是"Windows下编译TinyXML(XML文件解析)"的过程。

TinyXML挺好用的,不过有个缺陷就是不支持utf-16格式的XML解析,所以我最后选用了pugixml。

PugiXML教程:

Windows下用CMake编译PugiXML及配置测试-CSDN博客

如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关推荐
系统之家装机大师5 小时前
Win11 22H2/23H2系统11月可选更新KB5046732发布!
windows·电脑
系统之家装机大师5 小时前
微软发布Win11 24H2系统11月可选更新KB5046740!
windows·电脑
戎梓漩7 小时前
windows下安装curl,并集成到visual studio
ide·windows·visual studio
蓝田~9 小时前
观察者模式和订阅模式
windows·观察者模式
梓仁沐白15 小时前
ubuntu+windows双系统切换后蓝牙设备无法连接
windows·ubuntu
九鼎科技-Leo19 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
Yang.9921 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
我不瘦但很逗1 天前
Windows下使用DBeaver连接云数据库(MySQL)
数据库·windows
ashane13141 天前
Java list
java·windows·list
万里沧海寄云帆1 天前
Word 插入分节符页码更新问题
windows·microsoft·word