如何从文件系统填充XML树?

时间:2014-07-06 17:32:20

标签: c++ xml winapi

请帮忙。 我得到了一个代码,可以找到给定目录中的所有文件夹,子文件夹和文件。现在我需要在XML文档中编写它们。没有使用解析器可以吗?我应该添加什么?

void PrintDir(char *parm)
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind;

    char buffer[MAX_PATH];
    char path[MAX_PATH];

    strcpy(path, parm);
    strcat(path, "*.*");

    hFind = FindFirstFile(path, &FindFileData);

    do
    {
        if (!strcmp(FindFileData.cFileName, ".") || !strcmp(FindFileData.cFileName, ".."))
            continue;

        if (FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
        {
            strcpy(buffer, parm);
            strcat(buffer, FindFileData.cFileName);
            printf("%s\n", buffer);
            strcat(buffer, "\\");
            PrintDir(buffer);
        }
        else
        {
            strcpy(buffer, parm);
            strcat(buffer, FindFileData.cFileName);
            printf("%s\n", buffer);
        }  
    }while(FindNextFile(hFind, &FindFileData));

    FindClose(hFind);
}

2 个答案:

答案 0 :(得分:0)

我认为解决这个问题的最佳方式是"递归下降"通过文件系统。假设您希望XML层次结构与文件系统层次结构匹配,我认为您可以定义以下递归函数:

typedef boost::filesystem::path path;

void appendDirectoryToXML(const path& current_directory, XMLNode& current_node)
{
    for (subdirectory in directories(current_directory))
    {
       subirectory_xml_entry = new XML entry created in current_node;
       call appendDirectoryToXML(subdirectory, subirectory_xml_entry);
    }
    for (non_directory_file in files(current_directory))
    {
       add entry for non_directory_file to current_node;
    } 
}

以上是伪代码;具体细节将取决于文件系统库和您使用的XML库的详细信息。

答案 1 :(得分:0)

尝试这样的事情:

#include <string>
#include <tinyxml.h> 

void PrintDir(const std::string &parm, TiXmlElement *parentElement)
{
    WIN32_FIND_DATA FindFileData;
    std::vector<std::string> subFolders, files;

    HANDLE hFind = FindFirstFileA((parm + "*.*").c_str(), &FindFileData);
    if (hFind == INVALID_HANDLE_VALUE)
        return;

    do
    {
        if (!strcmp(FindFileData.cFileName, ".") || !strcmp(FindFileData.cFileName, ".."))
            continue;

        if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            subFolders.push_back(FindFileData.cFileName);
        else
            files.push_back(FindFileData.cFileName);
    }
    while (FindNextFile(hFind, &FindFileData));

    FindClose(hFind);

    // optionally sort files...
    // optionally sort subFolders...

    for (std::vector<std::string>::iterator i = files.begin(), end = files.end(); i != end; ++i)
    {
        printf("%s%s\n", parm.c_str(), i->c_str());

        TiXmlElement *fileElement = new TiXmlElement("File");
        fileElement->SetAttribute("name", *i);
        parentElement->LinkEndChild(fileElement);
    }
    files.clear();

    for (std::vector<std::string>::iterator i = subFolders.begin(), end = subFolders.end(); i != end; ++i)
    {
        printf("%s%s\n", parm.c_str(), i->c_str());

        TiXmlElement *fileElement = new TiXmlElement("Folder");
        folderElement->SetAttribute("name", *i);
        parentElement->LinkEndChild(folderElement);

        PrintDir(param + *i + "\\", folderElement);
    }
}

TiXmlDocument doc;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", "");
doc.LinkEndChild(decl);

TiXmlElement *filesystem = new TiXmlElement("FileSystem");
doc.LinkEndChild(filesystem);

TiXmlElement *driveElement = new TiXmlElement("Drive");
driveElement->SetAttribute("letter", "C");
filesystem->LinkEndChild(driveElement);

PrintDir("C:\\", driveElement);

doc.SaveFile("filesystem.xml");