zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C++读xml 文件信息

C++文件XML 信息
2023-09-27 14:25:49 时间

h

//
 2017的版本  Michael Wang 20180323
#ifdef  SceneHOld2017_Michael

#include "tinystr.h"
#include "tinyxml.h"

#include <atlconv.h>//wchar_t

#include "Modeling\ModelingData.h"

//	相关字符串的长度
#define	LEN_NAME       32
#define	LEN_DES           256

enum NodeType{ NODE_BASE = 200, NODE_SCENE, NODE_ASSEMBLY, NODE_PART };

class APNode
{
private:
	NodeType		nodeType;		// 节点类型
	//wchar_t			name[LEN_NAME];		// 节点名称
	__int32			counts;			// length of the byte array representation of the bojbect
	ID					id;
	char                 name[LEN_NAME];


public:
	NodeType type() { return nodeType; }

	inline int base_byte_size();
	inline virtual int byte_size() { return base_byte_size(); }

	//void SetName(wchar_t _name[]){ ; };
	void SetName(const char* _name){ strcpy(name, _name); }
	inline virtual void ToCharArray(char buf[], int index);


	APNode(NodeType type) : id(-1), nodeType(type), counts(0) {};
	APNode() : nodeType(NODE_BASE), counts(0) {};
	APNode(char buf[], int index);

	virtual ~APNode();
};

class PartNode : public APNode
{
private:
	__int32			m_nID;			// 零件ID,用于各个客户端和服务器之间通信
	ModelMesh		m_modelMesh;	// PlanA


public:
	ModelMesh& GetMesh() { return m_modelMesh; }

	inline int byte_size();
	virtual void ToCharArray(char buf[], int index);

	bool InitNode(TiXmlElement *xmlNode);

	PartNode() : APNode(NODE_PART) { };
	PartNode(char buf[], int index);

	virtual ~PartNode();
};

class AssemblyNode : public APNode
{
private:
	list<APNode*>	m_pListChildren;

public:
	inline int byte_size();
	virtual void ToCharArray(char buf[], int index);

	bool InitNode(TiXmlElement *xmlNode);

	void BrowseChildren(TiXmlElement* xmlParent, AssemblyNode* nodeParent);

	const list<APNode*>& Children() { return m_pListChildren; }
	void AppendChild(APNode* pNode) { m_pListChildren.push_back(pNode); }

	AssemblyNode() : APNode(NODE_ASSEMBLY) { };
	AssemblyNode(NodeType type) : APNode(type) { };
	AssemblyNode(char buf[], int index);

	virtual ~AssemblyNode();
};

class SceneNode : public AssemblyNode
{
private:
	int			    product_id ;			// 不急着加进去
	//wchar_t		description[LEN_DES];
	 char    description[LEN_DES];

	bool InitNode(TiXmlElement *xmlNode);

public:
	inline int byte_size();
	virtual void ToCharArray(char buf[], int index);

	void SetDescription(const char* _description){ strcpy(description, _description); }

	bool ReadXML(const char* path);

	SceneNode(char buf[], int index);
	SceneNode() : AssemblyNode(NODE_SCENE) { product_id = 0; };

	virtual ~SceneNode();
};

#endif /*SceneHOld2017_Michael*/

cpp


//
/2017的版本  Michael Wang 20180323
#ifdef  SceneCppOld2017_Michael
// **************************************************************************************************************************
// class APNode 
// **************************************************************************************************************************
APNode::APNode(char buf[], int index)
{
	// get value of nodetype
	int pos = index, len = sizeof(NodeType);
	memcpy_s(&nodeType, len, &buf[pos], len);
	pos += len;

	// get value of count
	len = sizeof(__int32);
	memcpy_s(&counts, len, &buf[pos], len);
	pos += len;

	// get value of type
	len = sizeof(ID);
	memcpy_s(&id, len, &buf[pos], len);
	pos += len;

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

}

APNode::~APNode()
{
};


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

	// copy byte count of the object
	int count = byte_size();
	len = sizeof(__int32);
	memcpy_s(&(buf[pos]), len, &count, len);
	pos += len;

	 copy id to buf 
	len = sizeof(ID);
	memcpy_s(&(buf[pos]), len, &id, len);
	pos += len;

	//int node = 0;
	//memcpy_s(&node, sizeof(__int32), &buf[44], sizeof(__int32));
	//name
	len = sizeof(char) * LEN_NAME;
	memcpy_s(&(buf[pos]), len, &name, len);

}

int APNode::base_byte_size()
{
	return sizeof(__int32)*2 + sizeof(char)* LEN_NAME + sizeof(__int32);
}

// **************************************************************************************************************************
// class PartNode
// **************************************************************************************************************************
PartNode::PartNode(char buf[], int index) : APNode(buf, index)
{

	//************************************
	int pos = index + base_byte_size();					// 找到父类数据的结束位置

	int len = sizeof(__int32);
	memcpy_s(&m_nID, len, &buf[pos], len);				// 拷贝零件ID
	pos += len;

	m_modelMesh = ModelMesh(buf, pos);        //m_modelMesh
	pos += m_modelMesh.byte_size();

}

PartNode::~PartNode()
{
};

int PartNode::byte_size()
{

	int len = base_byte_size();
	len += sizeof(__int32);								//m_nID
	len += m_modelMesh.byte_size();				//m_modelMesh
	
	return len;
}

void PartNode::ToCharArray(char buf[], int index)
{
	APNode::ToCharArray(buf, index);

	int pos = index + base_byte_size();
	int len = sizeof(__int32);
	memcpy_s(&(buf[pos]), len, &m_nID, len);
	pos += len;

	m_modelMesh.ToCharArray(buf, pos);
	len = m_modelMesh.byte_size();
	// wrong Michael Wang 20171204
	//int node = 0;
	//memcpy_s(&node, len, &buf[88], len);
}

bool PartNode::InitNode(TiXmlElement *xmlNode)
{
	if (strcmp("Part", xmlNode->Value()) == 0)
	{

		SetName(xmlNode->Attribute("name"));
		xmlNode->QueryIntAttribute("ID", &m_nID);

		//读取stl模型数据
		string partPaths = xmlNode->Attribute("path");
		const char* partChar = partPaths.c_str();
		if (strcmp("", partChar) != 0)
		{
			// string 和wchar_t的转化
			std::wstring widstr = std::wstring(partPaths.begin(), partPaths.end());
			wchar_t* pwidstr = const_cast<wchar_t*>(widstr.c_str());
			//USES_CONVERSION;
			//const	char* names = "hello";
			//const WCHAR* cLineChar = A2W(names);
			GetMesh().ReadSTL(pwidstr);
		}

		return true;
	}

	return false;
}

// **************************************************************************************************************************
// class AssemblyNode
// **************************************************************************************************************************
AssemblyNode::AssemblyNode(char buf[], int index) : APNode(buf, index)
{
	int pos = index + base_byte_size();					// 找到父类数据的结束位置

	int len = sizeof(__int32);
	int count;											                        // 子节点的数量
	memcpy_s(&count, len, &buf[pos], len);				// 拷贝子节点
	pos += len;

	for (int i = 0; i < count; i++)
	{
		NodeType type;										           // 子节点的类型
		memcpy_s(&type, sizeof(NodeType), &buf[pos], sizeof(NodeType));				// 拷贝子节点类型
		pos += sizeof(NodeType);

		switch (type)
		{
			case NODE_ASSEMBLY:
			{
				AssemblyNode *assembly = new AssemblyNode(buf, pos);
				pos += assembly->byte_size();
				//delete assembly;
				break;
			}
			case NODE_PART:
			{
				PartNode *part = new PartNode(buf, pos);
				pos += part->byte_size();
				//delete part;
				break;
			}
			default:
				break;
		}
	}
}

AssemblyNode::~AssemblyNode()
{
	for (list<APNode*>::iterator it = m_pListChildren.begin(); it != m_pListChildren.end(); it++)
		delete (*it);
	m_pListChildren.clear();
};

int AssemblyNode::byte_size()
{
	int len = base_byte_size();

	for (list<APNode*>::iterator it = m_pListChildren.begin(); it != m_pListChildren.end(); it++)
		len += (*it)->byte_size();

	return len;
}

void AssemblyNode::ToCharArray(char buf[], int index)
{
	APNode::ToCharArray(buf, index);			// 转换父类的数据

	int pos = index + base_byte_size();			// 转换完父类后的位置

	int len = sizeof(__int32);					// 增加一个整形数,表示子节点的数量
	int count = (int)m_pListChildren.size();			// 子节点的数量
	memcpy_s(&buf[pos], len, &count, len);		// copy count到buf
	pos += len;									// 位置发生偏移

	// 遍历子节点,copy子节点数据到buf
	for (list<APNode*>::iterator it = m_pListChildren.begin(); it != m_pListChildren.end(); it++)
	{
		(*it)->ToCharArray(buf, pos);

		pos += (*it)->byte_size();
	}

	int node = 0;
	memcpy_s(&node, sizeof(__int32), &buf[44], sizeof(__int32));
	//memcpy_s(&node, sizeof(__int32), &buf[48], sizeof(__int32));
}

bool AssemblyNode::InitNode(TiXmlElement *xmlNode)
{
	if (strcmp("Assembly", xmlNode->Value()) == 0)
	{
		//node->SetName(xmlNode->Attribute("name"));

		SetName(xmlNode->Attribute("name"));

		return true;
	}

	return false;
}

void AssemblyNode::BrowseChildren(TiXmlElement* xmlParent, AssemblyNode* nodeParent)
{
	TiXmlElement* child = xmlParent->FirstChildElement();			// 得到第一个孩子节点
	while (child != NULL)										// 如果孩子节点不为空
	{
		if (strcmp("Part", child->Value()) == 0)
		{
			PartNode* part = new PartNode();
			part->InitNode(child);
			nodeParent->AppendChild(part);
		}
		else if (strcmp("Assembly", child->Value()) == 0)
		{
			AssemblyNode* assembley = new AssemblyNode();
			assembley->InitNode(child);

			nodeParent->AppendChild(assembley);

			BrowseChildren(child, assembley);
		}

		child = child->NextSiblingElement();					// 找到下一个孩子节点
	}
}

// **************************************************************************************************************************
// class AssemblyNode
// **************************************************************************************************************************
SceneNode::SceneNode(char buf[], int index) : AssemblyNode(buf, index)
{
	int pos = index + base_byte_size();
	int len = sizeof(__int32);
	memcpy_s(&buf[pos], len, &product_id, len);
	pos += len;

	//len = sizeof(wchar_t) * LEN_DES;
	len = sizeof(char) * LEN_DES;
	memcpy_s(&description, len, &buf[pos], len);

}

SceneNode::~SceneNode()
{
};

int SceneNode::byte_size()
{
	//int len = base_byte_size();
	int len = AssemblyNode::byte_size();
	len += sizeof(__int32);
	//len += sizeof(wchar_t) * LEN_DES;
	len += sizeof(char) * LEN_DES;

	return len;
}

void SceneNode::ToCharArray(char buf[], int index)
{
	AssemblyNode::ToCharArray(buf, index);

	//int pos = index + base_byte_size();
	int pos = index + AssemblyNode::byte_size();
	memcpy_s(&buf[pos], sizeof(__int32), &product_id, sizeof(__int32));
	pos += sizeof(__int32);

	//int len = sizeof(wchar_t) * LEN_DES;
	int len = sizeof(char) * LEN_DES;
	memcpy_s(&buf[pos], len, &description, len);

}




bool SceneNode::InitNode(TiXmlElement* xmlNode)
{
	if (strcmp("scene_root", xmlNode->Value()) == 0)
	{
		//scene->SetName(xmlNode->Attribute("name"));
		//scene->SetDescription(xmlNode->Attribute("description"));
		SetDescription(xmlNode->Attribute("description"));
		xmlNode->QueryIntAttribute("productID", &product_id);

		return true;
	}

	return false;
}

bool SceneNode::ReadXML(const char* path)
{
	TiXmlDocument doc(path);											//打开XML文件
	if (!doc.LoadFile())												//检测打开是否成功
		return	false;

	TiXmlElement* xmlRoot = doc.RootElement();							//根元素
	if ( NULL == InitNode(xmlRoot) )
		return false;

	BrowseChildren(xmlRoot, this);

	return true;
}

#endif  /*SceneCppOld2017_Michael*/

xml

<?xml version="1.0" encoding="utf-8"?>
<scene_root children_count="3" name = "Sence" description = "SimpleScene" productID = 00>
	<Assembly children_count="2" name="BuJian1">
		<Assembly children_count="3" name="BuJian1-1">
			<Assembly children_count="2" name="BuJian1-1-1">
				<Part path="data/a.stl" name="LingJian1" ID = 01>
				</Part>
				<Part path="data/b.stl" name="LingJian2" ID = 2>
				</Part>
			</Assembly>
			<Part path="data/c.stl" name="LingJian3" ID = 3>
			</Part>
			<Part path="data/a.stl" name="LingJian4" ID = 4>
			</Part>
		</Assembly>
		<Part path="data/b.stl" name="LingJian5" ID = 5>
		</Part>
	</Assembly>
	<Part path="data/c.stl" name="LingJian6" ID = 6>
	</Part>
	<Part path="data/d.stl" name="LingJian7" ID = 7>
	</Part>
</scene_root>