服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++使用TinyXML解析XML

C++使用TinyXML解析XML

2022-07-20 12:16Frank.Ginger C/C++

本文详细讲解了C++使用TinyXML解析XML的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

1.介绍

Tinyxml的官方网址:http://www.grinninglizard.com

官方介绍文档:http://www.grinninglizard.com/tinyxmldocs/tutorial0.html

在TinyXML中,根据XML的各种元素来定义了一些类:

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

根据下图来说明常用的类对应的文本格式:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" ?> //TiXmlDeclaration,声明
<MyApp>    //TiXmlElement,元素
    <!-- Settings for MyApp -->//TiXmlComment,注释
    <Messages>//TiXmlElement,元素
        <Welcome>Welcome to MyApp</Welcome>
//<Welcome>是元素TiXmlElement ,“Welcome to MyApp”是TiXmlText,文本
        <Farewell>Thank you for using MyApp</Farewell>//同上
    </Messages>
    <Windows>//TiXmlElement,元素
        <Window name="MainFrame" x="5" y="15" w="400" h="250" />
// Window是元素TiXmlElement ,name、x、y、h是TiXmlAttribute
    </Windows>
    <Connection ip="192.168.0.1" timeout="123.456000" />
</MyApp>

TinyXML是个解析库,主要由DOM模型类(TiXmlBase、TiXmlNode、TiXmlAttribute、TiXmlComment、TiXmlDeclaration、TiXmlElement、TiXmlText、TiXmlUnknown)和操作类(TiXmlHandler)构成。它由两个头文件(.h文件)和四个CPP文件(.cpp文件)构成,用的时候,只要将(tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp)导入工程就可以用它的东西了。如果需要,可以将它做成自己的DLL来调用。

注意,TiXmlBase 是TiXmlNode的基类,TiXmlNode是TiXmlElement、TiXmlComment、TiXmlText、TiXmlDeclaration、TiXmlUnknown、TiXmlDocument的基类。

2.TinyXML配置

在stdafx.h头文件中增加头文件引用#include "tinyxml/tinyxml.h"

在工程设置中加入lib引用库

在stdafx.h中加入动态库引用

?
1
2
3
4
5
#ifdef _DEBUG
#pragma comment(lib,"TinyXMLD.lib")
#else
#pragma comment(lib,"TinyXML.lib")
#endif

3.TinyXML读取和保存文件

3.1 读取xml文件

?
1
2
3
4
5
TiXmlDocument lconfigXML;
if( !lconfigXML.LoadFile( strXmlFile.c_str() ) )
{
    break;
}

3.2 读取xml参数

?
1
2
3
4
5
6
7
TiXmlDocument lActionXML;
lActionXML.Parse(strRmcpParam.c_str());
if(lActionXML.Error())
{
     strErr = "输入参数不是标准的xml格式";
     return false;
 }

3.3 保存xml参数到文本

?
1
2
3
TiXmlDocument tyDoc;
tyDoc.SaveFile(m_strFilePath);

3.4 保存xml参数到临时变量

?
1
2
3
4
5
TiXmlDocument tyDoc;
TiXmlPrinter printer;
tyDoc.Accept(&printer);
std::string devParam = std::string(printer.CStr());

4.TinyXML增删改查

4.1 增

创建一个如1中的xml文件代码

?
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
void write_app_settings_doc( ) 
    TiXmlDocument doc; 
    TiXmlElement* msg;
     TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" ); 
    doc.LinkEndChild( decl );  
    TiXmlElement * root = new TiXmlElement( "MyApp" ); 
    doc.LinkEndChild( root ); 
    TiXmlComment * comment = new TiXmlComment();
    comment->SetValue(" Settings for MyApp " ); 
    root->LinkEndChild( comment );  
    TiXmlElement * msgs = new TiXmlElement( "Messages" ); 
    root->LinkEndChild( msgs );  
    msg = new TiXmlElement( "Welcome" ); 
    msg->LinkEndChild( new TiXmlText( "Welcome to MyApp" )); 
    msgs->LinkEndChild( msg );  
    msg = new TiXmlElement( "Farewell" ); 
    msg->LinkEndChild( new TiXmlText( "Thank you for using MyApp" )); 
    msgs->LinkEndChild( msg );  
    TiXmlElement * windows = new TiXmlElement( "Windows" ); 
    root->LinkEndChild( windows ); 
    TiXmlElement * window;
    window = new TiXmlElement( "Window" ); 
    windows->LinkEndChild( window ); 
    window->SetAttribute("name", "MainFrame");
    window->SetAttribute("x", 5);
    window->SetAttribute("y", 15);
    window->SetAttribute("w", 400);
    window->SetAttribute("h", 250);
    TiXmlElement * cxn = new TiXmlElement( "Connection" ); 
    root->LinkEndChild( cxn ); 
    cxn->SetAttribute("ip", "192.168.0.1");
    cxn->SetDoubleAttribute("timeout", 123.456); // floating point attrib
    dump_to_stdout( &doc );
    doc.SaveFile( "appsettings.xml" ); 
}

在节点最后插入新节点

?
1
TiXmlNode* LinkEndChild( TiXmlNode* addThis );

在节点后 前/后 插入新节点

?
1
2
TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );

4.2 删

删除某个节点, TiXmlNode是TiXmlElement、TiXmlComment、TiXmlText、TiXmlDeclaration、TiXmlUnknown、TiXmlDocument的基类

?
1
2
TiXmlNode node;
node.Clear();

从A节点上移除子节点B

?
1
2
TiXmlNode nodeA;
nodeA. RemoveChild( TiXmlNode* removeThis );

从元素A上移除名字为B的属性

?
1
2
TiXmlAttribute attrA;
attrA. RemoveAttribute( const char * name );

4.3 改

查找内容为<mfid val="1234" />,现需要将1234改成其他值

?
1
2
3
4
5
TiXmlNode* lpnode = NULL;
lpnode = tixml.RootElement()->IterateChildren("mfid",lpnode);
TiXmlAttribute* tiattr = lpnode->ToElement()->FirstAttribute();
//找到mfid节点,获取第一个属性值。注意,如果有多个属性值,需要判断哪个属性值是需要的
tiattr->SetValue(mfid.c_str());

替换一个节点

?
1
TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );

4.4 查

获取link节点

?
1
2
3
4
5
6
const TiXmlNode* lpItemNode = NULL;//初始化
lpItemNode = lconfigXML.RootElement()->IterateChildren("link", lpItemNode);
if (lpItemNode == NULL)
{
    //Can not find <link>break;
}

获取link节点中的type属性值

?
1
std::string strType = lpItemNode->ToElement()->Attribute("type");

遍历节点

?
1
2
3
4
5
6
7
8
9
10
11
const TiXmlNode* lpMapNode = NULL; //初始化
lpMapNode = lconfigXML.RootElement()->IterateChildren("node", lpMapNode);
if (lpMapNode)
{
    rms::CStationMapping litem;
    const TiXmlNode* lpItemNode = NULL ;
    while(lpItemNode = lpMapNode->IterateChildren("item",lpItemNode))
    {
        string str = lpItemNode->ToElement()->Attribute("ABC");
    }
}

遍历元素属性

?
1
2
3
4
5
TiXmlAttribute* pAttr = NULL;
for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next()) 
{   
  …
}

节点的下一个兄弟节点

?
1
const TiXmlNode* NextSibling() const;

元素的下一个元素

?
1
const TiXmlElement* NextSiblingElement() const;

属性的下一个属性

?
1
const TiXmlAttribute* Next() const;

返回值为NULL表示不存在

5.一个完整例子

?
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
void AppSettings::load(const char* pFilename)
{
    TiXmlDocument doc(pFilename);
    if (!doc.LoadFile()) return;
 
    TiXmlHandle hDoc(&doc);
    TiXmlElement* pElem;
    TiXmlHandle hRoot(0);
 
    // block: name
    {
        pElem=hDoc.FirstChildElement().Element();
        // should always have a valid root but handle gracefully if it does
        if (!pElem) return;
        m_name=pElem->Value();
 
        // save this for later
        hRoot=TiXmlHandle(pElem);
    }
 
    // block: string table
    {
        m_messages.clear(); // trash existing table
 
        pElem=hRoot.FirstChild( "Messages" ).FirstChild().Element();
        for( pElem; pElem; pElem=pElem->NextSiblingElement())
        {
            const char *pKey=pElem->Value();
            const char *pText=pElem->GetText();
            if (pKey && pText)
            {
                m_messages[pKey]=pText;
            }
        }
    }
 
    // block: windows
    {
        m_windows.clear(); // trash existing list
 
        TiXmlElement* pWindowNode=hRoot.FirstChild( "Windows" ).FirstChild().Element();
        for( pWindowNode; pWindowNode; pWindowNode=pWindowNode->NextSiblingElement())
        {
            WindowSettings w;
            const char *pName=pWindowNode->Attribute("name");
            if (pName) w.name=pName;
            
            pWindowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left as-is
            pWindowNode->QueryIntAttribute("y", &w.y);
            pWindowNode->QueryIntAttribute("w", &w.w);
            pWindowNode->QueryIntAttribute("hh", &w.h);
 
            m_windows.push_back(w);
        }
    }
 
    // block: connection
    {
        pElem=hRoot.FirstChild("Connection").Element();
        if (pElem)
        {
            m_connection.ip=pElem->Attribute("ip");
            pElem->QueryDoubleAttribute("timeout",&m_connection.timeout);
        }
    }
}

到此这篇关于C++使用TinyXML解析XML的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_32619837/article/details/87601131

延伸 · 阅读

精彩推荐
  • C/C++c语言中getch,getche,getchar的区别

    c语言中getch,getche,getchar的区别

    getche() 和getch()很相似,它也需要引入头文件conio.h,那它们之间的区别又在哪里呢?不同之处就在于getch()无返回显示,getche()有返回显示...

    C语言教程网5032020-12-28
  • C/C++深入c语言continue和break的区别详解

    深入c语言continue和break的区别详解

    本篇文章是对c语言中continue和break的区别进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网4452020-11-28
  • C/C++mac 配置Clion运行C和C++的环境的详细步骤

    mac 配置Clion运行C和C++的环境的详细步骤

    这篇文章主要介绍了mac 配置Clion运行C和C++的环境的步骤详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以...

    JunDream11972021-11-03
  • C/C++在C++中反射调用.NET的方法(三)

    在C++中反射调用.NET的方法(三)

    在.NET与C++之间传输集合数据的方法是怎么样的呢?接下来通过本文给大家分享在C++中反射调用.NET(三),需要的朋友参考下吧 ...

    深蓝医生5272021-04-29
  • C/C++简单讲解哈希表

    简单讲解哈希表

    本文主要介绍了哈希表简单知识及C语言实现哈希表实例,文中利用图片以及代码简单讲解了相关知识,感兴趣的小伙伴可以多多学习这篇文章...

    英雄哪里出来8822021-12-29
  • C/C++C++ 基于BFS算法的走迷宫自动寻路的实现

    C++ 基于BFS算法的走迷宫自动寻路的实现

    这篇文章主要为大家介绍了C++ 基于BFS算法实现走迷宫自动寻路,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    coolight76312022-02-24
  • C/C++C语言预处理详解

    C语言预处理详解

    这篇文章主要给大家介绍了关于C语言之预处理的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    少司命11582022-01-20
  • C/C++探讨C语言中关键字volatile的含义

    探讨C语言中关键字volatile的含义

    本篇文章是对C语言中关键字volatile的含义进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网2112020-12-10