用了一个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>