概念
TinyXML是一个开源的解析XML的解析库。解析库的模型通过解析XML文件,在内存中生成DOM模型,使得可以方便的遍历XML。
官方下载地址:https://sourceforge.net/projects/tinyxml/?source=directory
github下载地址:https://github.com/leethomason/tinyxml2
模型
主要有两大模型:SAX和DOM。
- SAX:基于事件的模型,基本工作流程是分析XML文档,当发现了一个新的元素时,产生一个对应事件,并调用相应的用户处理函数。这种方式占用内存少,速度快,但用户程序相应得会比较复杂;
- DOM:文档对象模型,分析整个XML文档,将整个文档分成多个元素(如书、章、节、段等),在内存中形成对应的树结构。同时,向用户提供一系列的接口来访问和编辑树结构。这种方式占用内存大,速度往往慢于SAX,但可以给用户提供一个面向对象的访问接口,对用户更为友好;
tinyXml类说明
TiXmlBase: 模型的基类;
TiXmlAttribute: 元素属性类;
TiXmlNode: 节点类;
TiXmlComment: 注释类;
TiXmlDeclaration: 申明类;
TiXmlDocument: 文档类,对应xml整个文档;
TiXmlElement: 元素节点类,可以包含子节点和TiXmlAttribute;
TiXmlText: 文本类;
TiXmlUnknown: 未知元素类;
TiXmlHandler: 操作类;
示例
#include <iostream>
#include "tinyxml.h"
using namespace std;
int main()
{
const char* testXml =
"<?xml version=\"1.0\" encoding='utf-8'?>\n"
"<root>\n"
"<Item priority=\"1\" type='red'> call red </Item>\n"
"<Item priority=\"2\" type='green'> call green </Item>\n"
"<Item priority=\"3\" type='black'> call black </Item>\n"
"</root>\n";
// 文件保存
{
TiXmlDocument doc("demotest.xml");
doc.Parse(testXml);
if (doc.Error())
{
printf("Error in %s: %s\n", doc.Value(), doc.ErrorDesc());
return -1;
}
if (!doc.SaveFile())
{
printf("Save file error, in %s: %s\n", doc.Value(), doc.ErrorDesc());
exit(1);
}
printf("save file success\n");
}
// 加载文件
{
TiXmlDocument doc("demotest.xml");
bool ok = doc.LoadFile();
if (!ok)
{
printf("Error in %s: %s\n", doc.Value(), doc.ErrorDesc());
return -1;
}
printf("load file success\n");
// 打印文件
doc.Print(stdout);
printf("\n");
{
// 打印文件
TiXmlPrinter printer;
doc.Accept(&printer);
fprintf(stdout, "%s", printer.CStr());
}
printf("\n");
{
// 方式1
// 1:
TiXmlNode* rootNode = doc.FirstChild("root");
printf("1:%s\n", rootNode->Value()); // "root"
TiXmlElement* rootElement = rootNode->ToElement();
printf("1:%s %s\n", rootElement->Value(), rootElement->GetText()); // "root" "(null)"
rootNode = rootElement->FirstChildElement();
TiXmlElement* itemElement = rootNode->ToElement();
printf("1:%s %s\n", itemElement->Value(), itemElement->GetText()); // "Item" "call red"
itemElement = itemElement->NextSiblingElement();
printf("1:%s %s\n", itemElement->Value(), itemElement->GetText()); // "Item" "call green"
itemElement = itemElement->NextSiblingElement();
printf("1:%s %s\n", itemElement->Value(), itemElement->GetText()); // "Item" "call black"
//rootElement->RemoveChild(itemElement);
TiXmlElement item("Item");
item.SetAttribute("priority", "4");
item.SetAttribute("type", "yellow");
TiXmlText text("call yellow");
item.InsertEndChild(text);
rootElement->InsertAfterChild(itemElement, item);
doc.SaveFile();
}
printf("\n");
{
// 4:
TiXmlNode* rootNode = doc.FirstChild();
printf("4:%s\n", rootNode->Value());
TiXmlElement* rootElement = rootNode->ToElement();
//printf("4:%s\n", rootElement->Value());
}
printf("\n");
{
// 方式2
// 2:
//判断头文件是否为空
TiXmlNode* node = doc.RootElement();
if (nullptr == node)
{
printf("Error in %s: %s\n", doc.Value(), doc.ErrorDesc());
return -1;
}
printf("2:%s\n", node->Value()); // "root"
{
node = node->FirstChild();
printf("2:%s\n", node->Value()); // "Item"
node = node->NextSibling();
assert(node);
printf("2:%s\n", node->Value());
}
}
}
printf("\n");
{
// 3:
TiXmlDocument doc;
doc.Parse(testXml);
TiXmlNode* rootNode = doc.FirstChild("root");
TiXmlElement* rootElement = rootNode->ToElement();
printf("3:%s\n", rootElement->Value()); // "root"
rootNode = rootElement->FirstChildElement();
TiXmlElement* itemElement = rootNode->ToElement();
int result = 0, val = -1;
result = itemElement->QueryIntAttribute("priority", &val);
printf("3:%d\n", val); // "1"
itemElement = itemElement->NextSiblingElement();
result = itemElement->QueryIntAttribute("priority", &val);
printf("3:%d\n", val); // "2"
itemElement = itemElement->NextSiblingElement();
result = itemElement->QueryIntAttribute("priority", &val);
printf("3:%d\n", val); // "3"
// ...
}
printf("\n");
{
std::shared_ptr<TiXmlDocument> doc = std::make_shared<TiXmlDocument>();
doc->Parse(testXml);
doc->Print(stdout);
}
{
TiXmlDocument doc;
doc.Parse(testXml);
TiXmlNode* rootNode = doc.RootElement();
{
for (auto node = rootNode->FirstChild(); node != nullptr; node = node->NextSibling())
{
TiXmlElement* itemElement = node->ToElement();
int result = 0, val = -1;
result = itemElement->QueryIntAttribute("priority", &val);
printf("5:%d %d\n", result, val);
}
}
}
system("pause");
return 0;
}
输出:
save file success
load file success
<?xml version="1.0" encoding="utf-8" ?>
<root>
<Item priority="1" type="red">call red</Item>
<Item priority="2" type="green">call green</Item>
<Item priority="3" type="black">call black</Item>
</root>
<?xml version="1.0" encoding="utf-8" ?>
<root>
<Item priority="1" type="red">call red</Item>
<Item priority="2" type="green">call green</Item>
<Item priority="3" type="black">call black</Item>
</root>
1:root
1:root (null)
1:Item call red
1:Item call green
1:Item call black
4:
2:root
2:Item
2:Item
3:root
3:1
3:2
3:3
<?xml version="1.0" encoding="utf-8" ?>
<root>
<Item priority="1" type="red">call red</Item>
<Item priority="2" type="green">call green</Item>
<Item priority="3" type="black">call black</Item>
</root>
5:0 1
5:0 2
5:0 3