作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
TinyXML是什么?
TinyXML是一个轻量级的C++ XML解析器,它提供了一种简单的方法来解析和操作XML文档。TinyXML被设计为易于使用和集成到C++项目中,并且非常适合处理小型XML文件。
以下是TinyXML的一些主要特点和优点:
-
轻量级: TinyXML的设计目标之一是保持代码库的小巧简洁,因此它非常适合用于嵌入式系统或具有资源限制的环境。
-
简单易用: TinyXML提供了简单直观的API,使得解析和操作XML文档变得容易。它的API设计使得开发人员可以快速上手并完成XML处理任务。
-
跨平台性: TinyXML是跨平台的,可以在各种操作系统上运行,包括Windows、Linux和Mac OS等。
-
开源: TinyXML是开源的,可以在许可证允许的情况下免费使用和修改。
-
支持XML解析和生成: TinyXML支持解析XML文档,并且可以将XML数据写入到文件或内存中。
-
适用于小型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博客
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!