新手小白,如有不对请赐教!!
上一篇文章说了我的实现思路,以及遇到的问题,如果有和我一样迷茫的小伙伴就去看看我的上一篇文章: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;
}
运行结果: