xml 文件树结构用c++读入并保存

h
class Base_NameID
{
public:
	NodeType		nodeType;		// 节点类型
	int counts;
	char name[LEN_NAME];
	char ID[LEN_ID];

public:
	NodeType type() { return nodeType; }
	void Set(const char * _name);
	inline int byte_size();
	virtual void ToCharArray(char buf[], int & index);

	//在定义时必须指定Node类型
	Base_NameID(NodeType type) : nodeType(type),counts(0) {};
	Base_NameID(char * buf, int  & index);
	Base_NameID();
	~Base_NameID();
};





//定义基类:开始、结束时间
class Base_StartEnd
{
public:
	int start;
	int end;
public:
	virtual	void ToCharArray(char buf[], int & index);
	//在定义时必须指定Node类型	
	Base_StartEnd(char * buf, int  & index);
	Base_StartEnd();
	~Base_StartEnd();
};



class Vector3d:public Base_StartEnd
{
public:
	NodeType		nodeType;		// 节点类型
	double value[3];
	//声明Vector类型,0:平移,1:旋转
	Vector3d(NodeType type);

	Vector3d(NodeType _type, double data[3]);
	Vector3d(char * data, int & index);
	void ToCharArray(char buf[], int & index);
	~Vector3d();
};

//三种,包括模型、工具、手,必须先指定节点类型
class GameObject : public Base_NameID, public Base_StartEnd
{
public:
	list<Vector3d * > animations;
	GameObject(char * data, int & index);
	void ToCharArray(char buf[], int & index);
	GameObject( NodeType type);
	~GameObject();
};


class Process : public Base_NameID, public Base_StartEnd
{
public:
	list<GameObject * > gameObjects;

	//hand
	//results
	Process(char * data, int & index);
	void ToCharArray(char buf[], int & index);

	Process();
	~Process();
};



class AssemblyOrder : public Base_NameID
{
public:
	Base_NameID*  user;
	Base_NameID* scene;
	list<Process*>  processes;
	Base_NameID* result;

	AssemblyOrder(char * data, int & index);

	bool ReadXML(const char* file);
	void WriteXML(const char* xmlPath);
	void EncodeAO(char buf[], int & index);


	AssemblyOrder();
	~AssemblyOrder();
};

string doubleToString(double num);
string doubleArrayToStringN(double data[], int count);
void CharToDoubleN(double *buf, int n, const char * content);

cpp

#include "Scene.h"
// *********************************************************************************************************
// class Base_NameID
// *********************************************************************************************************

void Base_NameID::Set(const char * _name)
{
	strncpy_s(name, _name, LEN_NAME);
}

Base_NameID::Base_NameID(char  *buf, int & index)
{
	// get value of nodetype
	int  len = sizeof(NodeType);
	memcpy_s(&nodeType, len, &buf[index], len);
	index += len;

	// all count
	len = sizeof(__int32);
	memcpy_s(&counts, len, &buf[index], len);
	index += len;

	// get value of name
	len = sizeof(char) * LEN_NAME;
	memcpy_s(&name, len, &buf[index], len);
	index += len;

	// get value of type
	len = sizeof(char) * LEN_ID;
	memcpy_s(&ID, len, &buf[index], len);
	index += len;
}

Base_NameID::~Base_NameID()
{

};

Base_NameID::Base_NameID()
{
	nodeType = NodeType::NODE_AO;
};

int Base_NameID::byte_size()
{
	int len = sizeof(__int32)*2 + sizeof(char)* LEN_NAME + sizeof(char)*LEN_ID;
	len += LEN_ADDRESS + 3 * sizeof(double) + 3 * sizeof(double) + 3 * sizeof(double);
	return len;
}

void Base_NameID::ToCharArray(char buf[], int  & index)
{
	// nodeType
	int len = sizeof(NodeType);
	memcpy_s(&(buf[index]), len, &nodeType, len);
	index += len;

	//counts 
	len = sizeof(__int32);
	memcpy_s(&(buf[index]), len, &counts, len);
	index += len;

	// copy byte count of the object
	len = sizeof(name);
	memcpy_s(&(buf[index]), len, name, len);
	index += len;

	 copy id to buf 
	len = sizeof(ID);
	memcpy_s(&(buf[index]), len, ID, len);
	index += len;
}
// ****************************************************************************************************************
// class Base_StartEnd
// *************************************************************************************************************

Base_StartEnd::Base_StartEnd(char  *buf, int & index)
{
	int  len = sizeof(int);
	memcpy_s(&start, len, &buf[index], len);
	index += len;

	// get value of type
	len = sizeof(int);
	memcpy_s(&end, len, &buf[index], len);
	index += len;
}

Base_StartEnd::~Base_StartEnd()
{
};
Base_StartEnd::Base_StartEnd()
{
};

void Base_StartEnd::ToCharArray(char buf[], int  & index)
{
	// copy byte count of the object
	int len = sizeof(int);
	memcpy_s(&(buf[index]), len, &start, len);
	index += len;

	 copy id to buf 
	len = sizeof(int);
	memcpy_s(&(buf[index]), len, &end, len);
	index += len;
}

// ***********************************************************************************************************
// class Vector3d
// ***********************************************************************************************************

Vector3d::Vector3d(NodeType type)
{
	nodeType = type;
}

Vector3d::~Vector3d()
{
}

Vector3d::Vector3d(NodeType _type, double data[3])
{
	nodeType = _type;
	value[0] = data[0];
	value[1] = data[1];
	value[2] = data[2];
}

Vector3d::Vector3d(char * data, int & index)
{

	int  len = sizeof(NodeType);
	memcpy_s(&nodeType, len, &data[index], len);
	index += len;

	Base_StartEnd * temp = new Base_StartEnd(data, index);
	start = temp->start;
	end = temp->end;

	len = sizeof(double);
	memcpy_s(&value[0], len, &(data[index]), len);
	index += len;

	len = sizeof(double);
	memcpy_s(&value[1], len, &(data[index]), len);
	index += len;

	len = sizeof(double);
	memcpy_s(&value[2], len, &(data[index]), len);
	index += len;
}
void Vector3d::ToCharArray(char buf[], int & index)
{
	// nodeType
	int len = sizeof(NodeType);
	memcpy_s(&(buf[index]), len, &nodeType, len);
	index += len;

	Base_StartEnd::ToCharArray(buf, index);

	len = sizeof(double);
	memcpy_s(&(buf[index]), len, &value[0], len);
	index += len;

	// copy byte count of the object
	len = sizeof(double);
	memcpy_s(&(buf[index]), len, &value[1], len);
	index += len;

	// copy byte count of the object
	len = sizeof(double);
	memcpy_s(&(buf[index]), len, &value[2], len);
	index += len;
}

// ****************************************************************************************************************
// class GameObject
// ****************************************************************************************************************

GameObject::GameObject(NodeType type) :Base_NameID(type)
{

}

GameObject::~GameObject()
{
}

GameObject::GameObject(char * data, int & index) :Base_NameID(data, index), Base_StartEnd(data, index)
{
	int count;
	int len = sizeof(int);
	memcpy_s(&count, len, &(data[index]), len);
	index += len;
	for (int i = 0; i < count; i++)
	{
		//Vector3d * vec = new Vector3d();
		animations.push_back(new Vector3d(data, index));
	}
}

void GameObject::ToCharArray(char buf[], int & index)
{
	Base_NameID::ToCharArray(buf, index);
	Base_StartEnd::ToCharArray(buf, index);

	int count = animations.size();
	int len = sizeof(int);
	memcpy_s(&(buf[index]), len, &count, len);
	index += len;

	for (list<Vector3d*>::iterator it = animations.begin(); it != animations.end(); it++)
	{
		(*it)->ToCharArray(buf, index);
	}
}

// **************************************************************************************************************
// class Process
// ************************************************************************************************************
Process::Process() :Base_NameID(NodeType::NODE_PROCESS)
{

}

Process::~Process()
{

}

Process::Process(char * data, int & index) :Base_NameID(data, index), Base_StartEnd(data, index)
{
	int count;
	int len = sizeof(int);
	memcpy_s(&count, len, &(data[index]), len);
	index += len;

	for (int i = 0; i < count; i++)
	{
		//Vector3d * vec = new Vector3d();
		gameObjects.push_back(new GameObject(data, index));
	}
}

void Process::ToCharArray(char buf[], int & index)
{
	Base_NameID::ToCharArray(buf, index);
	Base_StartEnd::ToCharArray(buf, index);

	int count = gameObjects.size();
	int len = sizeof(int);
	memcpy_s(&(buf[index]), len, &count, len);
	index += len;

	for (list<GameObject*>::iterator it = gameObjects.begin(); it != gameObjects.end(); it++)
	{
		(*it)->ToCharArray(buf, index);
	}
}

// **********************************************************************************************
// class AssemblyOrder
// *********************************************************************************************

AssemblyOrder::AssemblyOrder() :Base_NameID(NODE_AO)
{

	user = new Base_NameID();
	user->nodeType = NODE_USER;
	scene = new Base_NameID(NODE_SCENE);

	result = new Base_NameID(NODE_RESULT);
}

AssemblyOrder::~AssemblyOrder()
{
}

AssemblyOrder::AssemblyOrder(char * data, int& index) :Base_NameID(data, index)
{
	user = new Base_NameID(data, index);
	scene = new Base_NameID(data, index);

	int count;
	int len = sizeof(int);
	memcpy_s(&count, len, &(data[index]), len);
	index += len;

	for (int i = 0; i < count; i++)
	{
		processes.push_back(new Process(data, index));
	}


}

void AssemblyOrder::EncodeAO(char buf[], int &index)
{
	Base_NameID::ToCharArray(buf, index);

	user->ToCharArray(buf, index);
	scene->ToCharArray(buf, index);

	int count = processes.size();
	int	len = sizeof(int);
	memcpy_s(&(buf[index]), len, &count, len);
	index += len;

	for (list<Process*>::iterator it = processes.begin(); it != processes.end(); it++)
	{
		(*it)->ToCharArray(buf, index);
	}

	//	result->ToCharArray(buf, index);
	int aoNodeType = 203;
	memcpy_s(&(buf[0]), len, &aoNodeType, len);
	//counts 
	memcpy_s(&(buf[sizeof(__int32)]), len, &index, len);
}

void WriteAttributes_NameID(XMLElement * ele_Part, Base_NameID *baseProp)
{
	ele_Part->SetAttribute("name", baseProp->name);
	ele_Part->SetAttribute("ID", baseProp->ID);
}

void WriteAttributes_StartEnd(XMLElement * ele_Part, Base_StartEnd *baseProp)
{
	ele_Part->SetAttribute("start", baseProp->start);
	ele_Part->SetAttribute("end", baseProp->end);
}

void ReadAttributes_NameID(Base_NameID * baseProp, XMLElement * EleAssembly)
{
	strncpy_s(baseProp->name, EleAssembly->Attribute("name"), LEN_NAME);
	strncpy_s(baseProp->ID, EleAssembly->Attribute("ID"), LEN_ID);
}

void ReadAttributes_StartEnd(Base_StartEnd * baseProp, XMLElement * EleAssembly)
{
	baseProp->start = EleAssembly->IntAttribute("start");
	baseProp->end = EleAssembly->IntAttribute("end");
}

bool AssemblyOrder::ReadXML(const char* file)
{
	tinyxml2::XMLDocument docR;
	docR.LoadFile(file);
	if (docR.Error())
	{
		cout << "ERROR! XML file error!" << endl;
		return false;
	}

	docR.SaveFile("Formatted_AO.xml");
	XMLElement *ele_AO = docR.RootElement();
	ReadAttributes_NameID(this, ele_AO);

	XMLElement *ele_User = ele_AO->FirstChildElement("User");
	ReadAttributes_NameID(user, ele_User);
	ReadAttributes_NameID(scene, ele_AO->FirstChildElement("Scene"));

	XMLElement *ele_process = ele_AO->FirstChildElement("Process");

	while (ele_process != NULL)										// 如果孩子节点不为空
	{
		if (strcmp("Process", ele_process->Value()) == 0)
		{
			Process * path = new Process();

			ReadAttributes_NameID(path, ele_process);
			ReadAttributes_StartEnd(path, ele_process);

			XMLElement *ele_gameobject = ele_process->FirstChildElement();
			while (ele_gameobject != NULL)										// 如果孩子节点不为空
			{
				if (strcmp("Object", ele_gameobject->Value()) == 0 || strcmp("Tools", ele_gameobject->Value()) == 0)
				{
					GameObject * object;
					if (strcmp("Object", ele_gameobject->Value()) == 0)
						object = new GameObject(NodeType::NODE_OBJECT);

					if (strcmp("Tools", ele_gameobject->Value()) == 0)

						object = new GameObject(NodeType::NODE_TOOLS);

					ReadAttributes_NameID(object, ele_gameobject);
					ReadAttributes_StartEnd(object, ele_gameobject);

					XMLElement *ele_vector = ele_gameobject->FirstChildElement();
					while (ele_vector != NULL)										// 如果孩子节点不为空
					{
						if (strcmp("Translate", ele_vector->Value()) == 0)
						{
							Vector3d * vector = new Vector3d(NodeType::NODE_TRANSLATE);
							ReadAttributes_StartEnd(vector, ele_vector);
							CharToDoubleN(vector->value, 3, ele_vector->GetText());
							object->animations.push_back(vector);
						}
						if (strcmp("Rotate", ele_vector->Value()) == 0)
						{
							Vector3d * vector = new Vector3d(NodeType::NODE_ROTATE);
							ReadAttributes_StartEnd(vector, ele_vector);
							CharToDoubleN(vector->value, 3, ele_vector->GetText());
							object->animations.push_back(vector);
						}

						ele_vector = ele_vector->NextSiblingElement();
					}
					path->gameObjects.push_back(object);

				}
				if (strcmp("Hands", ele_gameobject->Value()) == 0)
				{

					//path->gameObjects.push_back(object);
				}
				ele_gameobject = ele_gameobject->NextSiblingElement();
			}
			processes.push_back(path);
		}
		ele_process = ele_process->NextSiblingElement();
	}

	//ReadAttributes(result, ele_AO->FirstChildElement("Result"));
	return  true;
}

void AssemblyOrder::WriteXML(const char* xmlPath)
{
	FILE* fp;
	fopen_s(&fp, xmlPath, "w+");//创建空xml文件
	fclose(fp);

	tinyxml2::XMLDocument doc;
	doc.LoadFile(xmlPath);//载入xml文件
	XMLDeclaration* declaration = doc.NewDeclaration();//添加xml文件头申明
	doc.InsertFirstChild(declaration);
	XMLElement *Root = doc.NewElement("AO");
	doc.InsertEndChild(Root);

	WriteAttributes_NameID(Root, this);

	//insert Head
	XMLElement* ele_User = doc.NewElement("User");
	Root->InsertEndChild(ele_User);
	WriteAttributes_NameID(ele_User, user);

	XMLElement* ele_Scene = doc.NewElement("Scene");
	Root->InsertEndChild(ele_Scene);
	WriteAttributes_NameID(ele_Scene, scene);

	//1
	for (list<Process*>::iterator it_process = processes.begin(); it_process != processes.end(); it_process++)
	{
		XMLElement* ele_Process = doc.NewElement("Process");
		Root->InsertEndChild(ele_Process);
		WriteAttributes_NameID(ele_Process, *it_process);
		WriteAttributes_StartEnd(ele_Process, *it_process);

		//2
		for (list<GameObject*>::iterator it_gameobject = (*it_process)->gameObjects.begin(); it_gameobject != (*it_process)->gameObjects.end(); it_gameobject++)
		{
			XMLElement* ele_GameObject;
			if ((*it_gameobject)->nodeType == NodeType::NODE_OBJECT)
			{
				ele_GameObject = doc.NewElement("Object");
			}
			else if ((*it_gameobject)->nodeType == NodeType::NODE_TOOLS)
			{
				ele_GameObject = doc.NewElement("Tools");
			}
			ele_Process->InsertEndChild(ele_GameObject);
			WriteAttributes_NameID(ele_GameObject, *it_gameobject);
			WriteAttributes_StartEnd(ele_GameObject, *it_gameobject);

			//3
			for (list<Vector3d*>::iterator it_vector = (*it_gameobject)->animations.begin(); it_vector != (*it_gameobject)->animations.end(); it_vector++)
			{
				XMLElement* ele_Vector;
				if ((*it_vector)->nodeType == NodeType::NODE_TRANSLATE)
				{
					ele_Vector = doc.NewElement("Translate");
				}
				else if ((*it_vector)->nodeType == NodeType::NODE_ROTATE)
				{
					ele_Vector = doc.NewElement("Rotate");
				}
				ele_GameObject->InsertEndChild(ele_Vector);
				WriteAttributes_StartEnd(ele_Vector, *it_vector);
			}
		}
	}
	/*
	XMLElement* ele_Result = doc.NewElement("Result");
	Root->InsertEndChild(ele_Result);
	WriteAttributes(ele_Result, result);*/

	doc.SaveFile(xmlPath);
}


xml


<?xml version="1.0"?>
<!-- 工序名字,作为根节点,属性为AO名字和ID编号-->
<AO name="process01" ID="AO1">
    <!--内容包含:操作人员、工具工装、零部件、如何操作(人和零部件的路径)、结果  -->
    <!--操作人员,制定名字和ID-->
    <User name="zhangli" ID="U01"/>
    <!--本AO对应的场景入口,需要和场景文件一致-->
    <Scene name="desk" ID="A01"/>
    <!--依次定义动画路径,包括动画对象(人、零件),平移和旋转矢量-->
    <!--一个工步,可以有多个-->
    <Process name="p1" ID="P1" start="0" end="1000">

	<!--操作的物体,可以有多个,但必须有-->
        <Object name="leg3" ID="P03" start="0" end="800">
            <Translate start="0" end="100">100 200 300</Translate>
            <Translate start="300" end="350">-50 0 30</Translate>
            <Rotate start="350" end="450">30 50 30</Rotate>
            <Translate start="450" end="800">30 50 60</Translate>
        </Object>

	<!--工具、工装,可以有多个,也可以没有-->

        <Tools name="tool1" ID="T01" start="500" end="1000">
            <Translate start="500" end="1000">100 200 300</Translate>
            <Translate start="500" end="1000">-50 0 30</Translate>
            <Rotate start="500" end="1000">30 50 30</Rotate>
            <Translate start="600" end="1000">30 50 60</Translate>
        </Tools>
		
	<!--手,可以有多个,也可以没有-->

        <Hands name="left" ID="Left" start="500" end="1000">
            <Translate PointID="1" start="500" end="1000">100 200 300</Translate>
            <Translate PointID="2" start="500" end="1000">-50 0 30</Translate>
            <Translate PointID="5" start="500" end="1000">30 50 60</Translate>
        </Hands>

	<!--对特定的工艺,result内的元素是明确的-->
        <Result>
            <Isfinished name="螺纹安装是否完成" value="yes/no"/>
            <Isfinished name="螺纹安装力矩" value="0.01牛米"/>
            <Isfinished name="螺纹安装缝隙" value="0.01mm"/>
        </Result>
    </Process>

	
</AO>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值