欢迎光临 Rick 's BLOG
日志首页  | C# .Net编程  | 原创作品  | 生活点滴  | C\C++相关  | 多媒体相关※ERMP  | VB相关  | 其它运维与编程  |  留言簿
vc6、vc7、vc8、vc9、vc10、vc11、vc12、vc14、vc15各代表Visual Studio C++什么版本
晴天  C++ 中 XML 库 TinyXML2 的基本使用方法
[ 发布日期:3周前 (12-06) ]   [ 来自:本站原创 ] [分类:C\C++相关]

一、前言


TinyXML-2 是一个简单,小型,高效的 C ++ XML 解析器,可以轻松集成到其他程序中。
直接引用源文件的话只需要包含两个文件(h 和 cpp,此外还有个测试文件里面带有 demo)。
TinyXML-2 解析 XML 文档,并以此为基础构建可读取,修改和保存的文档对象模型(DOM)。文档说,在解释 XML 时仅使用 UTF-8 编码,假定所有 XML 为 UTF-8 编码格式。
该库还支持打印到文件或内存,使用 XMLPrinter 类。

GitHub 链接:https://github.com/leethomason/tinyxml2

备用下载链接:tinyxml2-10.0.0.zip 



(下载库项目后带有离线英文文档,可以浏览器在线翻译即可)

二、基本使用方法



引入头文件:
#include "tinyxml2.h"
 
//tinyxml2的类在tinyxml2命名空间
using namespace tinyxml2;


使用 XMLDocument 加载和保存 XML 文件:
//构造一个xml文档类
XMLDocument doc;
//读取文件
//从磁盘加载XML文件。成功返回XML_SUCCESS(0),或者返回errorID。
XMLError error = doc.LoadFile(xmlPath);
//也可以解析字符串
//XMLError tinyxml2::XMLDocument::Parse(const char *xml,size_t nBytes = static_cast<size_t>(-1));
if (error != XMLError::XML_SUCCESS)
return;
//存储到文件,参数2 compact紧凑默认false
doc.SaveFile(xmlPath);


可以借助 XMLDocument 生成节点(元素、属性、文本、注释等),也可以直接 new 生成对象,但还要使用 Insert 方法才能插入到结构中:
//元素
XMLElement * tinyxml2::XMLDocument::NewElement (const char *name)
//注释
XMLComment * tinyxml2::XMLDocument::NewComment (const char *comment)
//文本
XMLText * tinyxml2::XMLDocument::NewText (const char *text) 
//XML文件头描述
XMLDeclaration * tinyxml2::XMLDocument::NewDeclaration (const char *text=0)
//未知类型
XMLUnknown * tinyxml2::XMLDocument::NewUnknown (const char *text)
 
//插入到末尾
XMLNode * tinyxml2::XMLNode::InsertEndChild (XMLNode *addThis)
//插入到开头
XMLNode * tinyxml2::XMLNode::InsertFirstChild (XMLNode *addThis)
//插入到节点的下一个位置
XMLNode * tinyxml2::XMLNode::InsertAfterChild (XMLNode *afterThis, XMLNode *addThis)


删除子节点:
//是否不包含子节点
bool tinyxml2::XMLNode::NoChildren () const
//第一个子节点
const XMLNode * tinyxml2::XMLNode::FirstChild () const
//第一个子元素 
const XMLElement * tinyxml2::XMLNode::FirstChildElement (const char *name=0) const
//最后一个子节点
const XMLNode * tinyxml2::XMLNode::LastChild () const
//最后一个子元素
const XMLElement * tinyxml2::XMLNode::LastChildElement (const char *name=0) const
//上一个兄弟节点 
const XMLNode * tinyxml2::XMLNode::PreviousSibling () const
//上一个兄弟元素 
const XMLElement * tinyxml2::XMLNode::PreviousSiblingElement (const char *name=0) const
//下一个兄弟节点
const XMLNode * tinyxml2::XMLNode::NextSibling () const
//下一个兄弟元素
const XMLElement * tinyxml2::XMLNode::NextSiblingElement (const char *name=0) const


如果要遍历整个文档,可从 XMLDocument 开始遍历,XXXChild + XXXSibling 遍历所有的子节点和兄弟节点。

三、简单完整示例代码


[复制到剪贴板]

#include <iostream>
#include <string>
 
#include "tinyxml2.h"
 
//tinyxml2的类在tinyxml2命名空间
using namespace tinyxml2;
 
//测试生成xml
void create_xml(const charxmlPath);
//测试解析xml
void parse_xml(const charxmlPath);
//遍历xml node
void traversal_node(XMLNodenode);
//遍历xml element
void traversal_element(XMLNodenodeint level);
//生成预定格式xml
void create_xml2(const charxmlPath);
//解析预定义格式xml
void parse_xml2(const charxmlPath);

int main()
{
    const 
charpath "./test.xml";
    
create_xml(path);
    
parse_xml(path);
 
    const 
charpath2 "./test2.xml";
    
create_xml2(path2);
    
parse_xml2(path2);
 
    
system("pause");
    return 
0;
}

void create_xml(const charxmlPath)
{
    
std::cout << "\ncreate_xml:" << xmlPath << std::endl;
    
//【】构造一个xml文档类
    
XMLDocument doc;
    
//【】操作文档相关接口
    //创建与此文档关联的新声明。对象的内存由文档管理。
    //如果'text'参数为null,则使用标准声明:
    //<?xml version="1.0" encoding="UTF-8"?>
    
XMLDeclarationdeclaration doc.NewDeclaration();
    
//创建与此文档关联的新元素。元素的内存由文档管理。
    
XMLElementelement doc.NewElement("ElementA");
    
//创建与此文档关联的新注释。注释的内存由文档管理。
    
XMLCommentcomment doc.NewComment("My TinyXml2 Test... ...");
    
//创建与此文档关联的新文本。文本的存储由文档管理。
    
XMLTexttext doc.NewText("Some Test");
    
//创建与此文档关联的新的未知节点。对象的内存由文档管理。
    
XMLUnknownunknown doc.NewUnknown("Unknown");
    
//【】创建了节点还要插入文档中
    //添加一个子节点作为最后一个(右)子节点。如果子节点已经是文档的一部分,则将其从其旧位置移至新位置。
    //XMLNode* tinyxml2::XMLNode::InsertEndChild(XMLNode * addThis);
    //添加一个子节点作为第一个(左)子节点。如果子节点已经是文档的一部分,则将其从其旧位置移至新位置。
    //XMLNode* tinyxml2::XMLNode::InsertFirstChild(XMLNode* addThis);
    //在指定的子节点之后添加一个节点。如果子节点已经是文档的一部分,则将其从其旧位置移至新位置。
    //XMLNode* tinyxml2::XMLNode::InsertAfterChild(XMLNode * afterThis, XMLNode * addThis);
    
doc.InsertFirstChild(declaration);
    
doc.InsertAfterChild(declarationelement);
    
doc.InsertEndChild(comment);
    
doc.InsertEndChild(text);
    
doc.InsertEndChild(unknown);
 
    
//【】操作节点相关接口
    //将命名属性设置为对应类型的value
    
element->SetAttribute("Level""A");
    
element->SetAttribute("Value"1992);
    
//设置文本
    
element->SetText("ElementA text");
    
//注释
    
element->InsertNewComment("ElementA comment");
    
//添加子节点,接口已经带insert功能了
    
XMLElementsub_element element->InsertNewChildElement("ElementB");
    
sub_element->SetAttribute("Level""B");
    
sub_element->SetText("ElementB text");
    
sub_element->InsertNewComment("ElementB comment");
 
 
    
//【】存储到文件,参数2 compact紧凑默认false
    //结构写的不规范,感觉应该拿一个根节点把那些注释,文本包起来
    //不然解析的时候没法访问啊
    
doc.SaveFile(xmlPath);
}

void parse_xml(const charxmlPath)
{
    
std::cout << "\nparse_xml:" << xmlPath << std::endl;
    
//【】构造一个xml文档类
    
XMLDocument doc;
    
//【】读取文件
    //从磁盘加载XML文件。成功返回XML_SUCCESS(0),或者返回errorID。
    
XMLError error doc.LoadFile(xmlPath);
    
//也可以解析字符串
    //从字符串解析XML文件。成功返回XML_SUCCESS(0),或者返回errorID。
    //XMLError tinyxml2::XMLDocument::Parse(const char *xml,size_t nBytes = static_cast<size_t>(-1));
    
if (error != XMLError::XML_SUCCESS)
        return;
    
//注意,实际解析时返回的指针记得判空,不然遇到解析失败异常就遭了
 
    //【】解析根元素
    //返回DOM的根元素。等效于FirstChildElement。要获取第一个节点,请使用FirstChild。
    
XMLElementroot doc.RootElement();
    
std::cout << "RootElement name:" << root->Name() << std::endl;
    
//获取第一个子元素,或者选择具有指定名称的第一个子元素。
    
XMLElementfirst doc.FirstChildElement("ElementA");
    
//给定一个属性名称,Attribute返回该名称的属性的值;如果不存在,则返回null。
    
std::cout << "FirstChildElement Attr Level:" << first->Attribute("Level") << std::endl;
    
std::cout << "FirstChildElement Attr Value:" << first->Attribute("Value") << std::endl;
    
//如果'this'的第一个Child是XMLText,则GetText返回Text节点的字符串,否则返回null。
    
std::cout << "FirstChildElement Text:" << first->GetText() << std::endl;
 
    
//【】解析子元素
    
XMLElementsub root->FirstChildElement("ElementB");
    
std::cout << "SubElement Attr Level:" << sub->Attribute("Level") << std::endl;
    
std::cout << "SubElement Text:" << sub->GetText() << std::endl;

        
//【】
    //可使用FirstChild+NextSibling遍历子节点
    
std::cout << "\ntraversal_xml:" << std::endl;
    
traversal_node(&doc);
    
//或者FirstChildElement+NextSiblingElement遍历子元素
    
std::cout << "\ntraversal_element:" << std::endl;
    
traversal_element(&doc0);
}
 
void traversal_node(XMLNodenode)
{
    if (!
node)
        return;
    for (
XMLNodecurrent node->FirstChild(); current != nullptrcurrent current->NextSibling())
    {
        
XMLNodetemp current;
        if (
temp->Value() != nullptr)
            
std::cout << temp->Value() << std::endl;
        if (!
temp->NoChildren())
            
traversal_node(temp);
    }
}

void traversal_element(XMLNodenodeint level)
{
    if (!
node)
        return;
    for (
XMLElementcurrent node->FirstChildElement(); current != nullptrcurrent current->NextSiblingElement())
    {
        
XMLElementtemp current;
        
//这里我使用点号来表示层级缩进
        
std::cout << std::string(level 5'.') << temp->Name() << std::endl;
        if (
temp->GetText() != nullptr)
            
std::cout << std::string(level 5'.') << "> Text" << ":" << temp->GetText() << std::endl;
        const 
XMLAttributeattr temp->FirstAttribute();
        if (
attr != nullptr)
            
std::cout << std::string(level 5'.') << "> Attr" << ":" << attr->Value() << std::endl;
        if (
temp->FirstChildElement() != nullptr)
            
traversal_element(templevel 1);
    }
}

void create_xml2(const charxmlPath)
{
    
std::cout << "\ncreate_xml2:" << xmlPath << std::endl;
    
//【】构造一个xml文档类
    
XMLDocument doc;
 
    
//【】构建我们的xml数据结构
    
XMLDeclarationdeclaration doc.NewDeclaration();
    
doc.InsertFirstChild(declaration);
    
//创建与此文档关联的新元素。元素的内存由文档管理。
    
XMLElementroot doc.NewElement("Root");
    
doc.InsertEndChild(root);
    
//子节点
    
XMLElementgroup_a root->InsertNewChildElement("GroupA");
    
group_a->SetAttribute("Type""A");
    
XMLElementa_1 group_a->InsertNewChildElement("Name");
    
a_1->SetText("中文");
    
XMLElementa_1_sub a_1->InsertNewChildElement("Content");
    
a_1_sub->SetText("111111");
    
XMLElementa_2 group_a->InsertNewChildElement("Name");
    
a_2->SetText("English");
    
XMLElementa_2_sub a_2->InsertNewChildElement("Content");
    
a_2_sub->SetText("222222");
    
XMLElementa_3 group_a->InsertNewChildElement("Name");
    
a_3->SetText("123");
    
XMLElementa_3_sub a_3->InsertNewChildElement("Content");
    
a_3_sub->SetText("333333");
    
XMLElementgroup_b root->InsertNewChildElement("GroupB");
    
group_b->SetAttribute("Type""B");
    
XMLElementgroup_c root->InsertNewChildElement("GroupC");
    
group_c->SetAttribute("Type""C");
 
    
//【】存储到文件,参数2 compact紧凑默认false
    
doc.SaveFile(xmlPath);
}

void parse_xml2(const charxmlPath)
{
    
std::cout << "\nparse_xml2:" << xmlPath << std::endl;
    
//【】构造一个xml文档类
    
XMLDocument doc;
    
//【】读取文件
    //从磁盘加载XML文件。成功返回XML_SUCCESS(0),或者返回errorID。
    
XMLError error doc.LoadFile(xmlPath);
    
//也可以解析字符串
    //从字符串解析XML文件。成功返回XML_SUCCESS(0),或者返回errorID。
    //XMLError tinyxml2::XMLDocument::Parse(const char *xml,size_t nBytes = static_cast<size_t>(-1));
    
if (error != XMLError::XML_SUCCESS)
        return;
    
//注意,实际解析时返回的指针记得判空,不然遇到解析失败异常就遭了
 
    //【】解析根节点
    //返回DOM的根元素。等效于FirstChildElement。要获取第一个节点,请使用FirstChild。
    
XMLElementroot doc.RootElement();
    
//【】查找
    
XMLElementfind_ele root->FirstChildElement("GroupA");
    if (
find_ele) {
        
std::cout << find_ele->Name() << std::endl;
        const 
XMLAttributeattr find_ele->FindAttribute("Type");
        if (
attr) {
            
std::cout << attr->Name() << ":" << attr->Value() << std::endl;
        }
        
XMLElementfind_sub find_ele->FirstChildElement("Name");
        if (
find_sub && find_sub->GetText()) {
            
std::cout << find_sub->GetText() << std::endl;
        }
    }

    
//【】遍历
    
std::cout << "\ntraversal_element:" << std::endl;
    
traversal_element(&doc0);


引用通告地址 (0):
复制引用地址https://www.rickw.cn/trackback/338
复制引用地址https://www.rickw.cn/trackback/338/GBK
[ 分类:C\C++相关  | 查看:113 ]

暂时没有评论,快来发表一个评论吧。
发表评论
作者:   用户:[访客] 
评论:

表  情
禁止表情 | 禁止UBB | 禁止图片 | 识别链接
对不起,你没有权限上传附件!
验证:
 
PoweredBy R-Blog V1.00 © 2004-2024 WWW.RICKW.CN, Processed in second(s) , 7 queries    京ICP备17058477号-5