基于tinyxml做的简单的xml解析。

1.创建xml

bool CreateXmlFile(string& szFileName)
{//创建xml文件,szFilePath为文件保存的路径,若创建成功返回true,否则false
try
{
//创建一个XML的文档对象。
TiXmlDocument *myDocument = new TiXmlDocument(); TiXmlElement *RootElement = new TiXmlElement("Response");
myDocument->LinkEndChild(RootElement); TiXmlElement *DeviceListElement = new TiXmlElement("DeviceList");
RootElement->LinkEndChild(DeviceListElement); DeviceListElement->SetAttribute("Num", ""); TiXmlElement *ItemElement = new TiXmlElement("Item");
DeviceListElement->LinkEndChild(ItemElement); TiXmlElement *DeviceIDElement = new TiXmlElement("DeviceID");
TiXmlElement *NameElement = new TiXmlElement("Name");
ItemElement->LinkEndChild(DeviceIDElement);
ItemElement->LinkEndChild(NameElement); TiXmlText *DeviceIDContent = new TiXmlText("");
TiXmlText *NameContent = new TiXmlText("测试平台");
DeviceIDElement->LinkEndChild(DeviceIDContent);
NameElement->LinkEndChild(NameContent); myDocument->SaveFile(szFileName.c_str());//保存到文件
}
catch (string& e)
{
return false;
}
return true;
}

创建出来的xml如下:

<Response>
<DeviceList Num="3">
<Item>
<DeviceID>44130000002000000002</DeviceID>
<Name>测试平台</Name>
</Item>
</DeviceList>
</Response>

2.读取xml

(1)从文件读取xml

bool ReadXmlFile(string& szFileName)
{//读取Xml文件,并遍历
try
{
//创建一个XML的文档对象。
TiXmlDocument *myDocument = new TiXmlDocument(szFileName.c_str());
myDocument->LoadFile();
//获得根元素,即Response。
TiXmlElement *RootElement = myDocument->RootElement();
//输出根元素名称,即输出Response。
cout << RootElement->Value() << endl;
//获得第一个DeviceList节点。
TiXmlElement *DeviceListElement = RootElement->FirstChildElement();
TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute();
cout << NumAttribute->Value()<< endl; //获得第一个Person的name节点和age节点和ID属性。
TiXmlElement *ItemElement = DeviceListElement->FirstChildElement();
for (int i = ; i < ; i++)
{
if (ItemElement)
{
TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement();
//这里注意判断是否存在,否则容易崩溃
if (DeviceIDElement && DeviceIDElement->FirstChild())
{
cout << DeviceIDElement->FirstChild()->Value() << endl; TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement();
if (NameElement && NameElement->FirstChild())
{
cout << NameElement->FirstChild()->Value() << endl; TiXmlElement *ParentIDElement = NameElement->NextSiblingElement();
if (ParentIDElement && ParentIDElement->FirstChild())
{
cout << ParentIDElement->FirstChild()->Value() << endl;
}
}
} ItemElement = ItemElement->NextSiblingElement();
}
}
}
catch (string& e)
{
return false;
}
return true;
}

(2)从字符串解析xml

bool ReadXmlString(string& xmlString, VEC_DEVICE& device_list)
{//读取Xml文件,并遍历
try
{
//创建一个XML的文档对象。
TiXmlDocument *myDocument = new TiXmlDocument();
myDocument->Parse(xmlString.c_str());
//获得根元素,即Response。
TiXmlElement *RootElement = myDocument->RootElement();
//输出根元素名称,即输出Response。
cout << RootElement->Value() << endl;
//获得第一个DeviceList节点。
TiXmlElement *DeviceListElement = RootElement->FirstChildElement();
TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute();
cout << NumAttribute->Value()<< endl; //获得第一个Person的name节点和age节点和ID属性。
TiXmlElement *ItemElement = DeviceListElement->FirstChildElement();
ST_DEVICE_INFO device_info ;
for (; ItemElement != NULL; ItemElement = ItemElement->NextSiblingElement())
{
if (ItemElement)
{
ST_DEVICE_INFO device_info;
TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement();
if (DeviceIDElement && DeviceIDElement->FirstChild())
{
string str = "";
str = DeviceIDElement->FirstChild()->Value();
//注意是否需要从utf-8转为GBK
device_info.m_strID = str.c_str();// UtfToGbk(str.c_str());
cout << "ID "<<device_info.m_strID.c_str()<< endl; TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement();
if (NameElement && NameElement->FirstChild())
{
str = "";
str = NameElement->FirstChild()->Value();
device_info.m_strName = str.c_str();// UtfToGbk(str.c_str());
cout << "name "<< device_info.m_strName << endl; TiXmlElement *ParentIDElement = NameElement->NextSiblingElement();
if (ParentIDElement && ParentIDElement->FirstChild())
{
str = "";
str = ParentIDElement->FirstChild()->Value();
device_info.m_strParentID = str.c_str();// UtfToGbk(str.c_str());
cout << "m_strParentID "<<device_info.m_strParentID.c_str()<< endl;
} device_info.m_nStatus = ; device_list.push_back(device_info);
}
}
else
{
continue;
}
}
}
}
catch (string& e)
{
return false;
}
return true;
}

从文件解析xml与从字符串解析xml的不同仅仅在加载xml的方式不同。

从文件是:

TiXmlDocument *myDocument = new TiXmlDocument(szFileName.c_str()); //szFileName为文件路径名
myDocument->LoadFile();

从字符串加载是:

TiXmlDocument *myDocument = new TiXmlDocument();
myDocument->Parse(xmlString.c_str()); //xmlString是字符串

如字符串可以为:

string xmlStr = "\
<?xml version=\"1.0\" encoding=\"utf - 8\" standalone=\"no\" ?> \
<Response>\
<DeviceList Num=\"3\">\
<Item>\
<DeviceID></DeviceID>\
<Name>测试平台</Name>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>惠州市</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
</DeviceList>\
</Response>" ;

有的时候需要从UTF-8转GBK,否则会乱码:

std::string UtfToGbk(const char* utf8)
{
int len = MultiByteToWideChar(CP_UTF8, , utf8, -, NULL, );
wchar_t* wstr = new wchar_t[len + ];
memset(wstr, , len + );
MultiByteToWideChar(CP_UTF8, , utf8, -, wstr, len);
len = WideCharToMultiByte(CP_ACP, , wstr, -, NULL, , NULL, NULL);
char* str = new char[len + ];
memset(str, , len + );
WideCharToMultiByte(CP_ACP, , wstr, -, str, len, NULL, NULL);
if (wstr) delete[] wstr;
return str;
}

3.完整的demo

以下是VS2013上的一个例子,搞怪的是utf-8转成GBK也不会乱码,转成GBK反而会乱码,原因不明。

// xmlTest.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h" #include <iostream>
#include <string>
#include <windows.h>
#include <atlstr.h>
#include <vector> #define TIXML_USE_STL
#include "tinyxml.h"
#include "tinystr.h" #pragma comment(lib,"tinyxmlSTL.lib") using namespace std; struct ST_DEVICE_INFO
{
string m_strID; //设备ID
string m_strParentID; //父ID
string m_strName; //设备名 int m_nType; //类型
int m_nStatus; //状态 float m_fLongitude; //经度
float m_fLatitude; //纬度 ST_DEVICE_INFO()
{
m_strID.clear();
m_strParentID.clear();
m_strName.clear(); m_nType = ;
m_nStatus = ; m_fLongitude = ;
m_fLatitude = ;
}
};
typedef vector<ST_DEVICE_INFO> VEC_DEVICE; std::string UtfToGbk(const char* utf8)
{
int len = MultiByteToWideChar(CP_UTF8, , utf8, -, NULL, );
wchar_t* wstr = new wchar_t[len + ];
memset(wstr, , len + );
MultiByteToWideChar(CP_UTF8, , utf8, -, wstr, len);
len = WideCharToMultiByte(CP_ACP, , wstr, -, NULL, , NULL, NULL);
char* str = new char[len + ];
memset(str, , len + );
WideCharToMultiByte(CP_ACP, , wstr, -, str, len, NULL, NULL);
if (wstr) delete[] wstr;
return str;
} bool CreateXmlFile(string& szFileName)
{//创建xml文件,szFilePath为文件保存的路径,若创建成功返回true,否则false
try
{
//创建一个XML的文档对象。
TiXmlDocument *myDocument = new TiXmlDocument(); TiXmlElement *RootElement = new TiXmlElement("Response");
myDocument->LinkEndChild(RootElement); TiXmlElement *DeviceListElement = new TiXmlElement("DeviceList");
RootElement->LinkEndChild(DeviceListElement); DeviceListElement->SetAttribute("Num", ""); TiXmlElement *ItemElement = new TiXmlElement("Item");
DeviceListElement->LinkEndChild(ItemElement); TiXmlElement *DeviceIDElement = new TiXmlElement("DeviceID");
TiXmlElement *NameElement = new TiXmlElement("Name");
ItemElement->LinkEndChild(DeviceIDElement);
ItemElement->LinkEndChild(NameElement); TiXmlText *DeviceIDContent = new TiXmlText("");
TiXmlText *NameContent = new TiXmlText("测试平台");
DeviceIDElement->LinkEndChild(DeviceIDContent);
NameElement->LinkEndChild(NameContent); myDocument->SaveFile(szFileName.c_str());//保存到文件
}
catch (string& e)
{
return false;
}
return true;
} bool ReadXmlFile(string& szFileName)
{//读取Xml文件,并遍历
try
{
//创建一个XML的文档对象。
TiXmlDocument *myDocument = new TiXmlDocument(szFileName.c_str());
myDocument->LoadFile();
//获得根元素,即Response。
TiXmlElement *RootElement = myDocument->RootElement();
//输出根元素名称,即输出Response。
cout << RootElement->Value() << endl;
//获得第一个DeviceList节点。
TiXmlElement *DeviceListElement = RootElement->FirstChildElement();
TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute();
cout << NumAttribute->Value()<< endl; //获得第一个Person的name节点和age节点和ID属性。
TiXmlElement *ItemElement = DeviceListElement->FirstChildElement();
for (int i = ; i < ; i++)
{
if (ItemElement)
{
TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement();
//这里注意判断是否存在,否则容易崩溃
if (DeviceIDElement && DeviceIDElement->FirstChild())
{
cout << DeviceIDElement->FirstChild()->Value() << endl; TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement();
if (NameElement && NameElement->FirstChild())
{
cout << NameElement->FirstChild()->Value() << endl; TiXmlElement *ParentIDElement = NameElement->NextSiblingElement();
if (ParentIDElement && ParentIDElement->FirstChild())
{
cout << ParentIDElement->FirstChild()->Value() << endl;
}
}
} ItemElement = ItemElement->NextSiblingElement();
}
}
}
catch (string& e)
{
return false;
}
return true;
} bool ReadXmlString(string& xmlString, VEC_DEVICE& device_list)
{//读取Xml文件,并遍历
try
{
//创建一个XML的文档对象。
TiXmlDocument *myDocument = new TiXmlDocument();
myDocument->Parse(xmlString.c_str());
//获得根元素,即Response。
TiXmlElement *RootElement = myDocument->RootElement();
//输出根元素名称,即输出Response。
cout << RootElement->Value() << endl;
//获得第一个DeviceList节点。
TiXmlElement *DeviceListElement = RootElement->FirstChildElement();
TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute();
cout << NumAttribute->Value()<< endl; //获得第一个Person的name节点和age节点和ID属性。
TiXmlElement *ItemElement = DeviceListElement->FirstChildElement();
ST_DEVICE_INFO device_info ;
for (; ItemElement != NULL; ItemElement = ItemElement->NextSiblingElement())
{
if (ItemElement)
{
ST_DEVICE_INFO device_info;
TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement();
if (DeviceIDElement && DeviceIDElement->FirstChild())
{
string str = "";
str = DeviceIDElement->FirstChild()->Value();
//注意是否需要从utf-8转为GBK
device_info.m_strID = str.c_str();// UtfToGbk(str.c_str());
cout << "ID "<<device_info.m_strID.c_str()<< endl; TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement();
if (NameElement && NameElement->FirstChild())
{
str = "";
str = NameElement->FirstChild()->Value();
device_info.m_strName = str.c_str();// UtfToGbk(str.c_str());
cout << "name "<< device_info.m_strName << endl; TiXmlElement *ParentIDElement = NameElement->NextSiblingElement();
if (ParentIDElement && ParentIDElement->FirstChild())
{
str = "";
str = ParentIDElement->FirstChild()->Value();
device_info.m_strParentID = str.c_str();// UtfToGbk(str.c_str());
cout << "m_strParentID "<<device_info.m_strParentID.c_str()<< endl;
} device_info.m_nStatus = ; device_list.push_back(device_info);
}
}
else
{
continue;
}
}
}
}
catch (string& e)
{
return false;
}
return true;
} int _tmain(int argc, _TCHAR* argv[])
{
string fileName = "test.xml";
CreateXmlFile(fileName); cout << "xml文件解析:" << endl;
ReadXmlFile(fileName); cout << endl;
cout << "字符串解析:" << endl; string xmlStr = "\
<?xml version=\"1.0\" encoding=\"utf - 8\" standalone=\"no\" ?> \
<Response>\
<DeviceList Num=\"3\">\
<Item>\
<DeviceID></DeviceID>\
<Name>测试平台</Name>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>惠州市</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
<Item>\
<DeviceID></DeviceID>\
<Name>邮政储蓄门口</Name>\
<ParentID></ParentID>\
</Item>\
</DeviceList>\
</Response>" ; VEC_DEVICE device_list ;
device_list.clear() ;
ReadXmlString(xmlStr, device_list) ;
cout << endl; for (int i = ; i < device_list.size(); i++)
{
cout<< "设备ID:" <<device_list[i].m_strID<<" 设备名称:"<<device_list[i].m_strName<<" 父ID: "<<device_list[i].m_strParentID<<endl ;
} system("pause"); return ;
}

运行结果:

完整工程地址:https://gitee.com/betterwgo/timyxml

tinyxml解析xml的更多相关文章

  1. C++ 使用TinyXML解析XML文件

    1.介绍 读取和设置xml配置文件是最常用的操作,TinyXML是一个开源的解析XML的C++解析库,能够在Windows或Linux中编译.这个解析库的模型通过解析XML文件,然后在内存中生成DOM ...

  2. 小知识积累-C++使用tinyxml解析Xml内存泄漏问题

    项目中需要用到C++解析XML,网上搜到tinyxml这么个开源库,就用了下试试,创建对象后内部自带Clear方法,但在循环测试的时候(刚用C++做项目不久,不会什么特别的内存泄漏测试工具,于是就写个 ...

  3. Cocos2d-x 3.0 使用TinyXml 解析XML文件

    在cocos2d-x 3.0中Xml解析已经不用自己找库了,已经为我们集成好了. text.xml <!--?xml version ="1.0" encoding =&qu ...

  4. cocos2d-x解析xml时的Bug

    cocos2d-x中使用tinyxml解析xml配置.如下: tinyxml2::XMLDocument doc; if (tinyxml2::XML_SUCCESS != doc.LoadFile( ...

  5. tinyXml直接解析XML字符串

    一直都用tinyxml直接LoadFile来解析XML,发现原来也可以直接解析XML字符串. XML文件: <?xml version=\"1.0\" encoding=\& ...

  6. iOS-数据解析XML解析的多种平台介绍

    在iPhone开发中,XML的解析有很多选择,iOS SDK提供了NSXMLParser和libxml2两个类库,另外还有很多第三方类库可选,例如TBXML.TouchXML.KissXML.Tiny ...

  7. 转:VC解析XML文件-CMarkup的使用详解

    本篇文章是对VC解析XML文件-CMarkup的使用进行了详细的分析介绍,需要的朋友参考下 VC解析XML文件的工具有很多,CMarkup, tinyXML,还有IBM的,MS的等等. 据说tinyX ...

  8. cocos2dx3.0-tinyxml在Android环境下解析xml失败的问题

    本文由@呆代待殆原创,转载请注明出处. 正常情况下,我们在用tinyxml读取xml文件的的时候,会像下面这样写. std::string filePath = FileUtils::getInsta ...

  9. Tinyxml 操作XML

    对于xml文件,目前的工作只是集中在配置文件和作为简单的信息文件来用,因此我不太喜欢使用msxml这种重量级的xml解析器,特别是使用msxml解析xml涉及到复杂的com类型转换,更是令人感觉繁琐. ...

随机推荐

  1. listview与adapter用法

    Android listview与adapter用法 listview与adapter用法 博客分类: android   一个ListView通常有两个职责. (1)将数据填充到布局. (2)处理用 ...

  2. 微信小程序组件navigator

    导航navigator:官方文档 Demo Code: // redirect.js navigator.js Page({ onLoad: function(options) { this.setD ...

  3. Myeclipse中is missing required source folder问题的解决

    最近在开发中,有好几次遇到is missing required source folder的问题,但是有些同事机器上却没有该问题,把整个工程删掉,重新从SVN上拿下来,问题依旧存在. 该问题出现后, ...

  4. ruby中的可调用对象--proc和lamdba

    ruby中将块转变成对象的三种方法 ruby中的大部分东西都是对象,但是块不是.那么,如果你想存下来一个块,方便以后使用,你就需要一个对象.ruby中有三种方法,把块转换成可以利用的对象. Proc. ...

  5. [C#]浮点数除零无法捕获异常的解决办法

    解决方法: //运算前先检查被除数是否为零,为零则手动抛出除零异常 if (numberB == 0.0) { throw new DivideByZeroException(); } Result ...

  6. 粗略介绍Java AQS的实现原理

    本文转自 http://www.importnew.com/24006.html 感谢作者 对我很有帮助 ①引言 AQS是JDK1.5提供的一个基于FIFO等待队列一个同步器的基础框架,java中的同 ...

  7. SpringBoot入门学习(二)

    第一讲我们已经讲解了入门Demo,这一讲我们主要讲解包含以下内容 项目内一些属性配置 自定义属性配置 ConfigurationProperties配置 (1)第一个工程创建的时候会自动在工程下创建a ...

  8. redis 简单命令操作

    一.概述: 在该系列的前几篇博客中,主要讲述的是与Redis数据类型相关的命令,如String.List.Set.Hashes和Sorted-Set.这些命令都具有一个共同点,即所有的操作都是针对与K ...

  9. WebSocket安卓客户端实现详解(一)–连接建立与重连

    http://blog.csdn.net/zly921112/article/details/72973054 前言 这里特别说明下因为WebSocket服务端是公司线上项目所以这里url和具体协议我 ...

  10. Python面试题目之Python的复制和赋值浅析

    python采用的是引用变量的结构,也就说如果你对一个变量赋值,并不是给这个变量开辟了一块内存空间而是将一个对象的内存空间地址告诉了这个变量,这样做的好处是便于管理,节省内存空间,便于内存释放等等.但 ...