tinyxml解析xml
基于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的更多相关文章
- C++ 使用TinyXML解析XML文件
1.介绍 读取和设置xml配置文件是最常用的操作,TinyXML是一个开源的解析XML的C++解析库,能够在Windows或Linux中编译.这个解析库的模型通过解析XML文件,然后在内存中生成DOM ...
- 小知识积累-C++使用tinyxml解析Xml内存泄漏问题
项目中需要用到C++解析XML,网上搜到tinyxml这么个开源库,就用了下试试,创建对象后内部自带Clear方法,但在循环测试的时候(刚用C++做项目不久,不会什么特别的内存泄漏测试工具,于是就写个 ...
- Cocos2d-x 3.0 使用TinyXml 解析XML文件
在cocos2d-x 3.0中Xml解析已经不用自己找库了,已经为我们集成好了. text.xml <!--?xml version ="1.0" encoding =&qu ...
- cocos2d-x解析xml时的Bug
cocos2d-x中使用tinyxml解析xml配置.如下: tinyxml2::XMLDocument doc; if (tinyxml2::XML_SUCCESS != doc.LoadFile( ...
- tinyXml直接解析XML字符串
一直都用tinyxml直接LoadFile来解析XML,发现原来也可以直接解析XML字符串. XML文件: <?xml version=\"1.0\" encoding=\& ...
- iOS-数据解析XML解析的多种平台介绍
在iPhone开发中,XML的解析有很多选择,iOS SDK提供了NSXMLParser和libxml2两个类库,另外还有很多第三方类库可选,例如TBXML.TouchXML.KissXML.Tiny ...
- 转:VC解析XML文件-CMarkup的使用详解
本篇文章是对VC解析XML文件-CMarkup的使用进行了详细的分析介绍,需要的朋友参考下 VC解析XML文件的工具有很多,CMarkup, tinyXML,还有IBM的,MS的等等. 据说tinyX ...
- cocos2dx3.0-tinyxml在Android环境下解析xml失败的问题
本文由@呆代待殆原创,转载请注明出处. 正常情况下,我们在用tinyxml读取xml文件的的时候,会像下面这样写. std::string filePath = FileUtils::getInsta ...
- Tinyxml 操作XML
对于xml文件,目前的工作只是集中在配置文件和作为简单的信息文件来用,因此我不太喜欢使用msxml这种重量级的xml解析器,特别是使用msxml解析xml涉及到复杂的com类型转换,更是令人感觉繁琐. ...
随机推荐
- PKU 1094 Sorting It All Out(拓扑排序)
题目大意:就是给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列. 是典型的拓扑排序,但输出格式上确有三种形式: 1.该字母序列有序,并依次输出: 2.判断该序列是否唯一: 3.该序列字母次序之间 ...
- Mybatis 一对一、一对多、多对多
一对一返回resultType <!-- 查询订单关联查询用户信息 resultType --> <select id="findOrderCustom" res ...
- 『NiFi 节点本地流与集群流不一致导致集群加入失败』问题解决
一.概述 在某些极端情况下,某些 NiFi 节点信息会由于用户强行 disconnect from cluster ,而出现 local flow 与 cluster 的 flow 不同步的问题. 此 ...
- 什么是Java中的原子操作( atomic operations)
1.啥是java的原子性 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行. 一个很经典的例子就是银行账户转账问题: 比如从账户A向账户B转1000元,那么 ...
- FileOutputStream写出数据实现换行和追加写入
FileOutputStream fos = fos = new FileOutputStream(Utils.getData(bizCtx,"strcat(getenv(HWORKDIR) ...
- MR案例:基站相关01
字段解释: product_no:用户手机号: lac_id:用户所在基站: start_time:用户在此基站的开始时间: staytime:用户在此基站的逗留时间. product_no lac_ ...
- python-作用域和装饰器
Python 作用域 学习的时机: 基本的数据类型 Python的运算 数字运算 + - * / // ** 逻辑运算 And or not 比较运算 > < == >= <= ...
- ImportError: No module named Crypto.PublicKey
答: sudo apt-get install python-pip (如果没有安装pip的话,需要这一操作) pip install pycrypto
- bat(续六)-windows批处理set命令
windows批处理set命令 [设置变量]格式:set 变量名=变量值详细:被设定的变量以%变量名%引用 [取消变量]格式:set 变量名=详细:取消后的变量若被引用%变量名%将为空 [展示变量]格 ...
- 爬虫框架Scrapy之Settings
Settings Scrapy设置(settings)提供了定制Scrapy组件的方法.可以控制包括核心(core),插件(extension),pipeline及spider组件.比如 设置Json ...