基于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. 机器学习第2周---炼数成金-----线性回归与Logistic

    重点归纳 回归分析就是利用样本(已知数据),产生拟合方程,从而(对未知数据)迚行预测用途:预测,判别合理性例子:利用身高预测体重:利用广告费用预测商品销售额:等等.线性回归分析:一元线性:多元线性:广 ...

  2. 测试:safenet提供的CheckKey函数 内存泄漏。具体来说是句柄.

    unsigned char vendor_code[] = "7XSQT4jxlSkDJhwqpxxfLwbuxgrYw93OMy+K5sc5pyfTa7HQo1ikLyg7FDuEpgUK ...

  3. Java io流详解四

    转载地址:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html 写在前面:本文章基本覆盖了java IO的全部内容,jav ...

  4. python16_day25【crm】

    一.CRM模拟admin功能 1.过滤功能 2.显示数据分页 3.动态菜单 项目:https://github.com/willianflasky/growup/tree/master/s16/hom ...

  5. apache服务器设置

    服务器目录 目录说明 bin: apache常用的一些命令 cgi-bin:存放一些脚本语言命令 conf:apache配置文件 error:错误记录 htodcs存放站点文件 logs:记录日志 m ...

  6. head中的title显示在body中

    今天遇到一个问题,就是title中的内容会显示在body中 <head> <title>324234</title> </head> 网上搜了一下是说编 ...

  7. 修改myeclipse字体与操作系统的字体一致

    如果你是win7系统,想要修改Myeclipse字体,步骤如下:第一步:C:\Windows\Fonts,找到Courier New,鼠标右键-->显示第二步:Ceneral --> Ap ...

  8. 20145103《JAVA程序设计》第十周学习总结

    网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据时,大部分的程序设 ...

  9. 20145216史婧瑶《Java程序设计》第三次实验报告

    实验三 敏捷开发与XP实践 实验内容 使用git上传代码,两个人进行小组合作,队友下载代码并修改再重新上传. 实验步骤 一. 使用git上传代码 1.找到需要push的文件所在文件夹,右键点击Git ...

  10. Git笔记之初识vi编辑器

    1.vi编辑器 如同Windows下的记事本,vi编辑器是Linux下的标配,通过它我们可以创建.编辑文件.它是一个随系统一起安装的文本编辑软件. vi编辑器提供了3种模式,分别是命令模式.插入模式. ...