vs2017、C++、读取XML文件,并获取里面的节点值-完整版程序

新手小白,如有不对请赐教!!

上一篇文章说了我的实现思路,以及遇到的问题,如果有和我一样迷茫的小伙伴就去看看我的上一篇文章:https://blog.csdn.net/qq_43688065/article/details/109599221

这篇直接上完整代码。

引入外部资源tinyXML后,创建一个read.cpp文件,在这里实现文件节点的获取。

程序结构:

要读取的XML文件:

<?xml version="1.0" encoding="gb2312"?>
<ROOT>
  <FeatruePoints>
    <FeatruePoint name="A-MQ1-1" recognize="1"/>
    <FeatruePoint name="A-MQ1-2" recognize="1"/>
    <FeatruePoint name="B-MH8-1" recognize="1"/>
    <FeatruePoint name="B-MH8-2" recognize="1"/>
    <FeatruePoint name="B-MH8-3" recognize="1"/>
    <FeatruePoint name="B-MH3-1" recognize="1"/>
    <FeatruePoint name="B-MH3-2" recognize="1"/>
    <FeatruePoint name="B-MH9-1" recognize="1"/>
    <FeatruePoint name="B-MH9-2" recognize="1"/>
    <FeatruePoint name="B-MH10-1" recognize="1"/>
    <FeatruePoint name="B-MH10-2" recognize="1"/>
    <FeatruePoint name="B-MH10-3" recognize="1"/>
    <FeatruePoint name="B-MH10-4" recognize="1"/>
    <FeatruePoint name="B-MH10-5" recognize="1"/>
  </FeatruePoints>
  <WeldPoints>
    <WeldPoint name="A-0-1" calculate="1" FeaturPoint1="A-MH-01"/>
    <WeldPoint name="A-0-2" calculate="1" FeaturPoint1="A-MH-02"/>
    <WeldPoint name="A-0-3" calculate="1" FeaturPoint1="A-MH-03"/>
    <WeldPoint name="A-1-1" calculate="2" FeaturPoint1="A-MQ1-1" FeaturPoint2="A-MQ1-2" FeaturPoint3="A-MH8-1" FeaturPoint4="A-MH3-1"/>
    <WeldPoint name="A-1-2" calculate="2" FeaturPoint1="A-MQ1-1" FeaturPoint2="A-MQ1-2" FeaturPoint3="A-MH8-2" FeaturPoint4="A-MH10-4"/>
    <WeldPoint name="A-1-3" calculate="2" FeaturPoint1="A-MQ1-3" FeaturPoint2="A-MQ1-4" FeaturPoint3="A-MH8-3" FeaturPoint4="A-MH10-5"/>
    <WeldPoint name="A-2-1" calculate="2" FeaturPoint1="A-MQ2-1" FeaturPoint2="A-MQ2-2" FeaturPoint3="A-MH8-1" FeaturPoint4="A-MH3-1"/>
    <WeldPoint name="A-2-2" calculate="2" FeaturPoint1="A-MQ2-1" FeaturPoint2="A-MQ2-2" FeaturPoint3="A-MH8-2" FeaturPoint4="A-MH10-4"/>
    <WeldPoint name="A-2-3" calculate="2" FeaturPoint1="A-MQ2-3" FeaturPoint2="A-MQ2-4" FeaturPoint3="A-MH8-3" FeaturPoint4="A-MH10-5"/>
  </WeldPoints>
  <Roads>
    <Road name="路径0,三点点焊">
      <Point name="A-0-1"/>
      <Point name="A-0-2"/>
      <Point name="A-0-3"/>
    </Road>
    <Road name="路径1">
      <Point name="A-1-1"/>
      <Point name="A-1-2"/>
      <Point name="A-1-3"/>
    </Road>
    <Road name="路径2">
      <Point name="A-2-1"/>
      <Point name="A-2-2"/>
      <Point name="A-2-3"/>
    </Road>
  </Roads>
  <Schemes>
    <Scheme name="点固">
      <WRoad name="路径0"/>
      <WRoad name="路径1"/>
      <WRoad name="路径2"/>
    </Scheme>
    <Scheme name="划线">
      <WRoad name="路径1"/>
      <WRoad name="路径2"/>
    </Scheme>
    <Scheme name="点焊">
      <WRoad name="路径1"/>
      <WRoad name="路径2"/>
    </Scheme>
    <Scheme name="连续">
      <WRoad name="路径1"/>
      <WRoad name="路径2"/>
    </Scheme>
  </Schemes>
</ROOT>

read.cpp

#include <iostream>
#include <string>
#include <vector>
#include "readXML/tinystr.h"
#include "readXML/tinyxml.h"
using namespace std;

struct FeaturePoints {//特征点的结构体
	string featurePointName;
	int recognize;
};
struct WeldPoints {//计算点结构体
	string weldPointName;
	int calculate;
	struct FeaturePoint {//这里使用结构体嵌套
		vector<string> featurePoint;
	}featpoint;//必须声明一个结构体变量,不然下面程序没法访问到FeaturePoint里面的属性
};
struct Roads {
	struct Road {//结构体嵌套
	string roadName;
	vector<string> pointName;
}road;//必须声明。解释同上
};

struct Schemes {
	struct Scheme {//结构体嵌套
	string schemeName;
	vector<string> wRoadName;
	}scheme;//必须声明。解释同上
};

//读取xml文件
int readXmlFile() {

	vector<FeaturePoints> featurepoints;//定义一个向量存储FeaturePoint
	FeaturePoints featus;//定义FeaturePoint的结构体变量

	TiXmlDocument mydoc("Config.xml");//xml文档对象
	bool loadOK = mydoc.LoadFile();//加载文档
	if (!loadOK) {//判断文件是否打开
		cout << "文件打开失败:" << mydoc.ErrorDesc() << endl;
		exit(1);
	}

	TiXmlElement *RootElement = mydoc.RootElement();//根元素
	cout << "根节点为" << RootElement->Value() << "\n";//输出ROOT

	TiXmlElement *pEle = RootElement;//根节点的指针
	TiXmlElement *FeatruePoints = RootElement->FirstChildElement();//根元素的第一个孩子节点<FeatruePoints>
	cout << "文件的第一个节点" <<FeatruePoints->Value()<< endl;//输出值为FeatruePoints

	//循环遍历FeatruePoints的孩子节点FeatruePoint     NextSiblingElement代表下一个兄弟节点
	for (TiXmlElement *FeaturePoint = FeatruePoints->FirstChildElement(); FeaturePoint != NULL;FeaturePoint=FeaturePoint->NextSiblingElement()) {
		TiXmlAttribute *pFeat = FeaturePoint->FirstAttribute();//获得FeaturePoint的第一个属性name
		TiXmlAttribute *pRec = pFeat->Next();//获得FeaturePoint的第二个属性recognize,tinyXML获取下个属性使用Next()
		string featurePointName = pFeat->Value();//得到第一个属性的值-->A-MQ1-1
		string recognize = pRec->Value();//得到第二个属性的值-->1
		int rec = std::stoi(recognize);//将string类型的recognize转换成int类型使用stoi,转换成其他类型使用方法一样
		featus.featurePointName = featurePointName;//将得到的name属性值存储在结构体
		featus.recognize = rec;//将得到的recoginize属性值存储在结构体中
		featurepoints.push_back(featus);//将他们存储在vector中
	}
	//循环输出--查看结果
	for (int i = 0; i < featurepoints.size();i++) {
		cout <<"FeatruePoint:"<<" "<<"name="<< featurepoints[i].featurePointName <<" "<<"recognize="<<featurepoints[i].recognize <<endl;
	}

	vector<WeldPoints> weldpoints;//使用向量存储第二个点信息
	WeldPoints welds;//创建结构体变量

	TiXmlElement *WeldPoints = FeatruePoints->NextSiblingElement();//得到FeaturePoints的兄弟节点WeldPoints
	cout << "文件中第二个要遍历的节点" << WeldPoints->Value() << endl;//输出WeldPoints

	//循环遍历WeldPoints的孩子节点WeldPoint
	for (TiXmlElement *WeldPoint = WeldPoints->FirstChildElement(); WeldPoint != NULL;WeldPoint=WeldPoint->NextSiblingElement()) {
		TiXmlAttribute *pWeldPoint = WeldPoint->FirstAttribute();//得到WeldPoint的第一个属性name
		TiXmlAttribute *pcalculate = pWeldPoint->Next();//得到WeldPoint的第二个属性recognize
		int cal = std::stoi(pcalculate->Value());//将string类型转换成interesting类型,C++中使用stoi
		//循环遍历pcalculate兄弟属性,并存储他们
		for (TiXmlAttribute *pWeld_FeaturPoint = pcalculate->Next(); pWeld_FeaturPoint != NULL;pWeld_FeaturPoint=pWeld_FeaturPoint->Next()) {
			//结构体嵌套要通过点.点.的形式去获取
			welds.featpoint.featurePoint.push_back (pWeld_FeaturPoint->Value());
		}
		welds.weldPointName = pWeldPoint->Value();//存储在WeldPoints结构体里面
		welds.calculate = cal;//存储属性值
		weldpoints.push_back(welds);//将整个结构体存储在vector向量里面
		welds.featpoint.featurePoint.clear();//将存储的点清除,下一个循环就会存储新的属性信息
	}

	//循环输出--查看结果
	for (int j = 0; j < weldpoints.size();j++) {
		cout << "WeldPoints:" << " " << "name=" << weldpoints[j].weldPointName << " " << "calculate=" << weldpoints[j].calculate<<" ";
		for (int r = 0; r < weldpoints[j].featpoint.featurePoint.size();r++) {
			cout<<" "<<"featurePoint=" << weldpoints[j].featpoint.featurePoint[r];
		}
		cout << endl;
	}

	struct Roads roads;//结构体变量
	vector<Roads> vec_Roads;//定义vector向量用来存储Road

	TiXmlElement *Roads = WeldPoints->NextSiblingElement();//获得文本文件中的第三个节点Roads
	cout << "文件中第三个要遍历的节点" << Roads->Value() << endl;//输出Roads

	//循环遍历Roads,获取孩子节点Road   NextSiblingElement代表下一个兄弟节点
	for (TiXmlElement *Road = Roads->FirstChildElement(); Road != NULL;Road=Road->NextSiblingElement()) {
		TiXmlAttribute *pAttr = Road->FirstAttribute();//获得Road的属性 name
		roads.road.roadName = pAttr->Value();//将他们存储在双层结构体里的roadName
		//循环遍历road的孩子节点
		for (TiXmlElement *point = Road->FirstChildElement(); point != NULL;point=point->NextSiblingElement()) {
			TiXmlAttribute *pPoint = point->FirstAttribute();//获得point的属性 name
			roads.road.pointName.push_back(pPoint->Value());//将获得的point name的属性值-->路径0,三点点焊,并存储在结构体中
		}
		vec_Roads.push_back(roads);//将结构体roads存储在vec_Roads里面
		roads.road.pointName.clear();//清空结构体里pointName
	}
	//循环输出--查看结果
	for (int t = 0; t < vec_Roads.size();t++) {
		cout << "Road name=" << vec_Roads[t].road.roadName << " ";
		for (int w = 0; w < vec_Roads[t].road.pointName.size();w++) {
			cout <<" "<< "Point name="<< vec_Roads[t].road.pointName[w];
		}
		cout << endl;
	}

	struct Schemes Sche;//定义结构体变量
	vector<Schemes> vec_Schemes;//定义vector存储Schemes
	TiXmlElement *Schemes = Roads->NextSiblingElement();//得到要循环遍历的第四个节点--Schemes
	cout << "文件中第四个要遍历的节点" << Schemes->Value()<<endl;

	//循环遍历第四个节点的孩子节点
	for (TiXmlElement *Scheme = Schemes->FirstChildElement(); Scheme != NULL;Scheme=Scheme->NextSiblingElement()) {
		TiXmlAttribute *pAttribute = Scheme->FirstAttribute();//得到Scheme的属性-->name
		Sche.scheme.schemeName = pAttribute->Value();//存储name的属性值-->点固
		//循环遍历Scheme的孩子节点--得到WRoad 
		for (TiXmlElement *WRoad = Scheme->FirstChildElement(); WRoad != NULL;WRoad=WRoad->NextSiblingElement()) {
			TiXmlAttribute *pWRoad = WRoad->FirstAttribute();//得到WRoad 的属性-->name
			Sche.scheme.wRoadName.push_back(pWRoad->Value());//将得到name的属性值-->路径0,存储在结构体中
		}
		vec_Schemes.push_back(Sche);//将Sche存储在vec_Schemes里面
		Sche.scheme.wRoadName.clear();//清空Sche.scheme.wRoadName里面存储的数据
	}

	//循环输出-->查看结果
	for (int k = 0; k < vec_Schemes.size(); k++) {
		cout <<"Scheme name="<<vec_Schemes[k].scheme.schemeName<<" ";
		for (int p = 0; p < vec_Schemes[k].scheme.wRoadName.size();p++) {
			cout <<" "<<"WRoad name="<<vec_Schemes[k].scheme.wRoadName[p];
		}
		cout << endl;	
	}
	return 1;
}
int main() {
	//下面这句是为了处理中文乱码加的,但是刚加的确实可以处理中文乱码问题,
	//后来不知道因为什么,不加这句话也好使了
	//system("chcp 65001");
	readXmlFile();
	system("pause");
	return 0;
}

运行结果:

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
如果需要源码可以发送邮件到sdiwen1982@sohu.com索取 /*************************************** 功能:读取xml文件 参数:[in] xml文件路径 返回:true读取成功 false读取失败 **************************************/ bool ReadXml(CString sXmlPath /*xml文件路径*/); /*************************************** 功能:写入xml文件 参数:[in] xml文件路径 返回:true写入成功 false写入失败 **************************************/ bool WriteXml(CString sXmlPath /*xml文件路径*/); /*************************************** 功能:释放空间 参数:无 返回:无 **************************************/ void Release(); /*************************************** 功能:删除指定的节点 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteNode(); /*************************************** 功能:删除当前节点的所有子节点,当前节点不删除 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAllSon(); /*************************************** 功能:根据索引删除子节点 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteSonByIndex(unsigned int nIndex); /*************************************** 功能:删除节点所有属性 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAllAttr(); /*************************************** 功能:根据属性名删除属性 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAttrByName(CString sName); /*************************************** 功能:根据索引删除属性 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAttrByIndex(unsigned int nIndex); /*************************************** 功能:根据属性名设置属性 参数:[in] sName 属性名 [in] sValue 属性 返回:true设置成功 false设置失败 **************************************/ bool SetAttrValueByName(CString sName, CString sValue); /*************************************** 功能:插入属性 参数:[in] sName 属性名 [in] sValue 属性 返回:true插入成功 false插入失败 **************************************/ bool InsertAttr(CString sName, CString sValue); /*************************************** 功能:设置节点 参数:[in] sValue 属性 返回:true设置节点成功 false设置节点失败 **************************************/ bool SetNodeValue(CString sValue); /*************************************** 功能:插入子节点 参数:[in] sName 节点名 返回:非空表示插入节点成功,返回插入的新节点指针 空表示插入失败 **************************************/ CXMLNode * InsertNode(CString sName); /*************************************** 功能:判断是否存在子节点 参数:[in] pNode 子节点文件指针, 返回:false没有子节点 true有子节点 **************************************/ bool HasChild(MSXML2::IXMLDOMNodePtr pNode);
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值