tinyXML2
是一款非常轻便的第三方操作xml
文件的C++
库,现在网络上许多教程都是基于tinyXML2
,为此制作了以下的demo。tinyXML2可以从官网去下载,也可以去github
下载。本Blog
使用的是tinyXML2
的6.0.2版本作为讲解。同时,本博客也将附上本demo
的下载地址,读者可以自己去测试。
首先,tinyXML2
使用起来方便,既可以将其生成dll库,也可以直接将tinyXML2
拉到项目中。为了方便起见,本文直接将库的源码拉到项目文件中。
假设,我们在一个视觉项目中使用多个相机,那么每个相机将会有ID
、 IP
地址、曝光时间、触发模式等属性。所以我们就想有类似下面的配置文件:
<CameraI>
<DevID>5DevID>
<IpAddress>178.26.85.83IpAddress>
<SubnetMask>123.45.67.89SubnetMask>
<ExposureAuto>falseExposureAuto>
<ExposureTime>200ExposureTime>
<TriggerMode>falseTriggerMode>
CameraI>
<CameraII>
<DevID>5DevID>
<IpAddress>178.26.85.83IpAddress>
<SubnetMask>123.45.67.89SubnetMask>
<ExposureAuto>falseExposureAuto>
<ExposureTime>200ExposureTime>
<TriggerMode>falseTriggerMode>
CameraII>
<CameraIII>
<DevID>5DevID>
<IpAddress>178.26.85.83IpAddress>
<SubnetMask>123.45.67.89SubnetMask>
<ExposureAuto>falseExposureAuto>
<ExposureTime>200ExposureTime>
<TriggerMode>falseTriggerMode>
CameraIII>
针对以上情况,我们得写一个怎么去读,怎么去写,怎么去修改属性的代码。下面将附上测试代码,希望读者通过调试来掌握tinyXML2
的调用方法。
/**
* 开发环境: VS2015 + TinyXML2 6.0.2 + Windows 10
* 硬件环境: CPU i7-8750H; RAM 8G; Gpu: GTX1050Ti
*
* 建议通过IDE调试来学习
*/
#include
#include "tinyxml2_6.2.0/tinyxml2.h"
/** @brief 读取每个相机的属性
@param p 相机节点指针
*/
static void ReadOneCameraAttribute(const tinyxml2::XMLElement* p)
{
int devIdContent = p->FirstChildElement("DevID")->IntText();
const char* ipAddrContent = p->FirstChildElement("IpAddress")->GetText();
const char* subnetMaskContent = p->FirstChildElement("SubnetMask")->GetText();
const char* exposureAutoContent = p->FirstChildElement("ExposureAuto")->GetText();
int64_t exposureTimeContent = p->FirstChildElement("ExposureTime")->Int64Text();
bool triggerModeContent = p->FirstChildElement("TriggerMode")->BoolText();
std::cout << "devIdContent(int):\t" << devIdContent << std::endl;
std::cout << "ipAddrContent:\t" << ipAddrContent << std::endl;
std::cout << "subnetMaskContent:\t" << subnetMaskContent << std::endl;
std::cout << "exposureAutoContent:\t" << exposureAutoContent << std::endl;
std::cout << "exposureTimeContent(int64_t):\t" << exposureTimeContent << std::endl;
std::cout << "triggerModeContent(bool):\t" << ((triggerModeContent == true) ? "true" : "false") << std::endl;
}
/** @brief 读取解析某路径的xml文件
@param path xml文件路径
*/
static void ReadParam(const std::string& path)
{
// 导入文件错误, 退出
tinyxml2::XMLDocument doc;
tinyxml2::XMLError error = doc.LoadFile(path.c_str());
if (error != tinyxml2::XMLError::XML_SUCCESS) return;
// 三个相机指针
tinyxml2::XMLElement* pFirst = doc.FirstChildElement("CameraI");
tinyxml2::XMLElement* pSecond = doc.FirstChildElement("CameraII");
tinyxml2::XMLElement* pThree = doc.FirstChildElement("CameraIII");
// 分别读取每个相机的各个属性
ReadOneCameraAttribute(pFirst); std::cout << "------------------\n";
ReadOneCameraAttribute(pSecond); std::cout << "------------------\n";
ReadOneCameraAttribute(pThree); std::cout << "------------------\n";
}
/** @brief 修改相机属性
@param p 相机节点指针
*/
static void ModifyOneCamera(tinyxml2::XMLElement* p)
{
int devId = 4;
const char* ipAddr = "139.66.38.13";
const char* subnetMask = "255.0.0.0";
bool exposureAuto = false;
int64_t exposureTime = 80;
bool triggerMode = false;
p->FirstChildElement("DevID")->SetText(devId);
p->FirstChildElement("IpAddress")->SetText(ipAddr);
p->FirstChildElement("SubnetMask")->SetText(subnetMask);
p->FirstChildElement("ExposureAuto")->SetText(exposureAuto);
p->FirstChildElement("ExposureTime")->SetText(exposureTime);
p->FirstChildElement("TriggerMode")->SetText(triggerMode);
}
/** @brief 修改某xml文件的参数
@param path xml文件路径
*/
static void ModifyParam(const std::string& path)
{
// 导入文件错误, 退出
tinyxml2::XMLDocument doc;
tinyxml2::XMLError error = doc.LoadFile(path.c_str());
if (error != tinyxml2::XMLError::XML_SUCCESS) return;
// 三个相机指针
tinyxml2::XMLElement* pFirst = doc.FirstChildElement("CameraI");
tinyxml2::XMLElement* pSecond = doc.FirstChildElement("CameraII");
tinyxml2::XMLElement* pThree = doc.FirstChildElement("CameraIII");
// 修改
ModifyOneCamera(pFirst);
ModifyOneCamera(pSecond);
ModifyOneCamera(pThree);
doc.SaveFile(path.c_str());
}
/** @brief 写相机属性. 产生完了之后将所有节点挂在p下面
@param p 某个相机节点
@param doc 所有的元素属性以及值均在doc的下面
*/
static void WriteOneCameraAttibute(tinyxml2::XMLElement* p, tinyxml2::XMLDocument& doc)
{
const char* ipAddr = "178.26.85.83";
const char* subnetMask = "123.45.67.89";
int64_t exposureTime = 200;
tinyxml2::XMLElement* pDevID = doc.NewElement("DevID");
tinyxml2::XMLText* pDevIdText = doc.NewText("5");
pDevID->InsertEndChild(pDevIdText);
p->InsertEndChild(pDevID);
tinyxml2::XMLElement* pIpAddr = doc.NewElement("IpAddress");
tinyxml2::XMLText* pIpAddrText = doc.NewText(ipAddr);
pIpAddr->InsertEndChild(pIpAddrText);
p->InsertEndChild(pIpAddr);
tinyxml2::XMLElement* pSubnetMask = doc.NewElement("SubnetMask");
tinyxml2::XMLText* pSubnetMaskText = doc.NewText(subnetMask);
pSubnetMask->InsertEndChild(pSubnetMaskText);
p->InsertEndChild(pSubnetMask);
tinyxml2::XMLElement* pExposureAuto = doc.NewElement("ExposureAuto");
tinyxml2::XMLText* pExposureAutoText = doc.NewText("false");
pExposureAuto->InsertEndChild(pExposureAutoText);
p->InsertEndChild(pExposureAuto);
tinyxml2::XMLElement* pExposureTime = doc.NewElement("ExposureTime");
tinyxml2::XMLText* pExposureTimeText = doc.NewText("200");
pExposureTime->InsertEndChild(pExposureTimeText);
p->InsertEndChild(pExposureTime);
tinyxml2::XMLElement* pTriggerMode = doc.NewElement("TriggerMode");
tinyxml2::XMLText* pTriggerModeText = doc.NewText("false");
pTriggerMode->InsertEndChild(pTriggerModeText);
p->InsertEndChild(pTriggerMode);
}
/** @brief 将数据写到某个xml文件中
@param path xml文件路径
*/
static void WriteParam(const std::string& path)
{
tinyxml2::XMLDocument doc;
const char* declaration = "";
doc.Parse(declaration);
tinyxml2::XMLElement* pFirst = doc.NewElement("CameraI");
WriteOneCameraAttibute(pFirst, doc);
doc.InsertEndChild(pFirst);
tinyxml2::XMLElement* pSecond = doc.NewElement("CameraII");
WriteOneCameraAttibute(pSecond, doc);
doc.InsertEndChild(pSecond);
tinyxml2::XMLElement* pThree = doc.NewElement("CameraIII");
WriteOneCameraAttibute(pThree, doc);
doc.InsertEndChild(pThree);
doc.SaveFile(path.c_str());
}
void test_CameraXML()
{
std::string path = "../Resources/camera_info.xml";
std::cout << "---------------生成一个xml文件------------------" << std::endl;
WriteParam(path);
std::cout << "--------------写文件结束,读取生成的xml文件------------------" << std::endl;
ReadParam(path);
std::cout << "--------------读文件结束,修改文件开始------------------" << std::endl;
ModifyParam(path);
}