C++ 树层级存储
用了一个map来记录所有的层级关系,然后从root找起,依次找出所有的节点…
// 用的是tinyXML读取
BOOL CXmlRead::ReadGroupInfo( std::map<CString, std::vector<std::pair<CString, BOOL>>> &mapGroup )
{
// 载入文件
TiXmlDocument *doc = new TiXmlDocument(PATH);
if (!doc->LoadFile())
{
delete doc;
return FALSE;
}
// 获取根节点
TiXmlElement *pRoot = doc->FirstChildElement(_T("TableGroup"));
ASSERT(pRoot);
if (pRoot == NULL)
{
delete doc;
return FALSE;
}
mapGroup.clear();
std::vector<std::pair<CString, BOOL>> vecTable;
TiXmlElement *pNode = dynamic_cast<TiXmlElement *>(pRoot->FirstChildElement());
while (pNode != NULL)
{
// 节点属性
CString strSubName = pNode->Attribute(_T("Name"));
vecTable.push_back(std::make_pair(strSubName, TRUE));
ASSERT(_T("Group") == (CString)(pNode->Value()));
if(!ReadNode(pNode, mapGroup))
{
return FALSE;
}
// 下一关键字节点
pNode = dynamic_cast<TiXmlElement *>(pNode->NextSiblingElement());
}
mapGroup[_T("ROOT")] = vecTable;
delete doc;
return TRUE;
}
BOOL CXmlRead::ReadNode(TiXmlElement *pNode, std::map<CString, std::vector<std::pair<CString, BOOL>>> &mapGroup)
{
// 每次添加的新节点应该是之前没有出现过的,否则会死循环
CString strNodeName = pNode->Attribute(_T("Name"));
if(mapGroup.end() != mapGroup.find(strNodeName)) return FALSE;
std::vector<std::pair<CString, BOOL>> vecTable;
TiXmlElement *pSubNode = dynamic_cast<TiXmlElement *>(pNode->FirstChildElement());
while (pSubNode != NULL)
{
// 节点名
CString strSub = pSubNode->Value();
// 节点属性
CString strSubName = pSubNode->Attribute(_T("Name"));
if(_T("Group") == strSub)
{
vecTable.push_back(std::make_pair(strSubName, TRUE));
if(!ReadNode(pSubNode, mapGroup))
{
return FALSE;
}
}
else if(_T("Table") == strSub)
{
vecTable.push_back(std::make_pair(strSubName, FALSE));
}
// 下一关键字节点
pSubNode = dynamic_cast<TiXmlElement *>(pSubNode->NextSiblingElement());
}
mapGroup[strNodeName] = vecTable;
return TRUE;
}
其实vector里面的bool是可以不要的,最初加这个只是为了区分树节点和叶节点…
不过还是有一点点不满意的地方…
根那个地方,我取名叫root因为我确定我的数据表没有叫root的,其实换成GUID可能会更好一点,因为万一有重名节点是会出现死循环的…
XML类似这种
<?xml version="1.0" encoding="gb2312" ?>
<TableGroup>
<Group Name = "A">
<Group Name = "A1">
<Group Name = "A11">
<Table Name = "A111" />
<Table Name = "A112" />
<Table Name = "A113" />
</Group>
<Group Name = "A12">
<Table Name = "A121" />
</Group>
</Group>
<Group Name = "A2">
<Group Name = "A21">
<Table Name = "A211)" />
</Group>
<Group Name = "A22">
<Table Name = "A221" />
<Table Name = "A222" />
</Group>
</Group>
</Group>
<Group Name = "B">
<Table Name = "B1" />
<Table Name = "B2" />
</Group>
<Group Name = "C">
<Table Name = "C1" />
<Table Name = "C2" />
<Table Name = "C3" />
</Group>
</TableGroup>