设置依赖性

在Project –> Project Dependencies设置项目依赖性,Mobile Radio依赖于TinyXML。
如果使用在Windows Mobile环境下,需要更改下面的代码。
// Microsoft compiler security
FILE* TiXmlFOpen( const char* filename, const char* mode )
{
//#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
// FILE* fp = 0;
// errno_t err = fopen_s( &fp, filename, mode );
// if ( !err && fp )
// return fp;
// return 0;
//#else
// return fopen( filename, mode );
//#endif
return fopen( filename, mode );
}
tinyxml.cpp文件
//#define TIXML_SAFE
#define TIXML_SSCANF sscanf
tinyxml.h文件
环境搭建完毕。
使用
使用TinyXML是一个愉悦的过程,所有使用的例子都可以在源代码的xmltest.cpp文件里面找到。所以强烈建议学习和使用TinyXML前先认真阅读xmltest.cpp的代码。
简单讲一下XML文件的结构,XML的结构就是层次性(Hierarchy)文件,包含Element(节点)和Attribute(属性),下面我保留英文,因为TinyXML的接口就也是使用同样的术语。Element就是节点,可以包含Attribute和子Element(Child Elements),Attribute就是Element的属性。
下面是Mobile Radio使用TinyXML的代码。
#include "include/tinyXML/tinyXML.h"
使用TinyXML只需要引用一个头文件就可以了。
const char* CONFIGPATH = "Config\\Stations.xml";
void CMobileRadioView::LoadConfig()
{
std::string p = GetCurrentPath() + std::string(CONFIGPATH);
TiXmlDocument document = TiXmlDocument(p.c_str());
if(!document.LoadFile())
{
MessageBox(L"Can not open the config file.");
return;
}
TiXmlHandle docHandle(&document);
TiXmlElement* cityElement = docHandle.FirstChild("stations").FirstChild("city").Element();
Station* station;
std::string city;
while (cityElement)
{
city = cityElement->Attribute("name");
TiXmlElement* stationElement = cityElement->FirstChildElement("station");
while (stationElement)
{
station = new Station();
station->City = city;
station->Id = atoi(stationElement->Attribute("sid"));
station->Name = stationElement->Attribute("name");
station->Image = stationElement->Attribute("image");
station->Stream = stationElement->Attribute("stream");
station->Website = stationElement->Attribute("website");
stationMap[station->Id] = station;
cityStationMap.insert(CityStationMap::value_type(station->City, station));
stationElement = stationElement->NextSiblingElement();
}
cityElement = cityElement->NextSiblingElement();
}
}
这是读取XML配置的代码,XML配置文件的结构可以参考 转换Json到XML的JavaScript实现 。大体的文件结构是分两层,第一层是城市,第二层是具体的电台信息。
TiXmlDocument document = TiXmlDocument(p.c_str());
if(!document.LoadFile())
{
MessageBox(L"Can not open the config file.");
return;
}
把XML配置文件加载到TiXmlDocument里。
TiXmlHandle docHandle(&document);
根据TiXmlDocument生成TiXmlHandle。
TiXmlElement* cityElement = docHandle.FirstChild("stations").FirstChild("city").Element();
TinyXML不直接支持XPath,所以只能一层层读,从根节点逐层查找。如果需要XPath支持,可以参考TinyXPath (http://tinyxpath.sourceforge.net)。
while (cityElement)
{
city = cityElement->Attribute("name");
TiXmlElement* stationElement = cityElement->FirstChildElement("station");
while (stationElement)
{
station = new Station();
station->City = city;
station->Id = atoi(stationElement->Attribute("sid"));
station->Name = stationElement->Attribute("name");
station->Image = stationElement->Attribute("image");
station->Stream = stationElement->Attribute("stream");
station->Website = stationElement->Attribute("website");
stationMap[station->Id] = station;
cityStationMap.insert(CityStationMap::value_type(station->City, station));
stationElement = stationElement->NextSiblingElement();
}
cityElement = cityElement->NextSiblingElement();
}
循环取出城市(City)和电台(Station)信息,FirstChildElement()查找第一个子Element。NextSiblingElement()用于读取同一层的兄弟Element,Attribute可以取出Element的Attribute。关于更多的读取例子,请看xmltest.cpp的代码。
上述例子把XML配置信息读取到C++的map和multimap里面。这两个容器的定义如下:
//Id -> Station
typedef std::map<int, Station*> StationMap;
//City -> Station
typedef std::multimap<std::string, Station*> CityStationMap;
StationMap保存ID和电台信息,一对一。CityStationMap保存城市和电台信息,一对多。