需要帮助使用Boost属性树库和XML递归创建目录树

时间:2015-05-15 04:28:49

标签: c++ xml recursion boost

我创建了一个表示项目目录布局的XML文件。它看起来像这样:

<folder>
    <folder>
        <name>src</name>
        <file>
            <name>main.cpp</name>
        </file>
    </folder>
    <file>
        <name>Makefile</name>
    </file>
    <file>
        <name>README.md</name>
    </file>
</folder>

我使用Boost属性树(boost::property_tree::ptree)来解析,表示和创建目录(我尝试编写的程序是一个生成空C ++项目的命令行工具)。我试图编写一个以递归方式创建目录的函数,但我以前从未使用过这个库,目前我遇到了几个心理块,感觉我正在考虑这一切错误。如果有人之前使用过这个库,可以给我一些关于我的代码的指示,我会很感激。这就是我到目前为止所拥有的:

static void create_directory_tree(std::string &root_name,
    boost::property_tree::ptree &directory_tree)
{
    // Create the root folder.
    boost::filesystem::create_directory(root_name);

    for (auto &tree_value : directory_tree.get_child("folder"))
    {
        // If the child is a file, create an empty file with the
        // name attribute.
        if (tree_value.first == "file")
        {
            std::ofstream file(tree_value.second.get<std::string>("name"));
            file << std::flush;
            file.close();
        }

        // If the child is a folder, call this function again with
        // the folder as the root. I don't understand the data
        // structure enough to know how to access this for my
        // second parameter.
        else if (tree_value.first == "folder")
        {
            create_directory_tree(tree_value.second.get<std::string>("name"), /* ??? */)
        }

        // If it's not a file or folder, something's wrong with the XML file.
        else
        {
            throw std::runtime_error("");
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我不清楚你在问什么。

我希望我对它有所帮助:

<强> Live On Coliru

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/filesystem.hpp>

#include <iostream>

using namespace boost::property_tree;
namespace fs = boost::filesystem;

namespace project_definition {
    void apply(ptree const& def, fs::path const& rootFolder) {
        for (auto node : def) {
            if ("folder" == node.first) {
                fs::path where = rootFolder / node.second.get<std::string>("name");
                fs::create_directories(where);

                apply(node.second, where);
            }
            if ("file" == node.first) {
                std::ofstream((rootFolder / node.second.get<std::string>("name")).native(), std::ios::trunc);
            }
        }
    }
}

int main()
{
    ptree projdef;
    read_xml("input.txt", projdef);

    try {
        project_definition::apply(projdef, "./rootfolder/");
    } catch(std::exception const& e)
    {
        std::cerr << e.what() << "\n";
    }
}

input.txt

<folder>
    <name>project</name>
    <folder>
        <name>src</name>
        <file><name>main.cpp</name></file>
    </folder>
    <file><name>Makefile</name></file>
    <file><name>README.md</name></file>
</folder>

创建一个结构:

./rootfolder
./rootfolder/project
./rootfolder/project/README.md
./rootfolder/project/src
./rootfolder/project/src/main.cpp
./rootfolder/project/Makefile