带有子句到JSON的Python文件夹结构

时间:2016-09-13 22:40:16

标签: python json jstree

我有一个脚本可以将任何给定的文件夹结构转换为JSON,JSTree兼容结构。但是,子文件夹全部归入一个级别的子级。因此文件夹中的文件夹只标记为根目录下的一个级别。我怎样才能在JSON中维护root-child-child关系?

import os, sys, json

def all_dirs_with_subdirs(path, subdirs):

    try:
        path = os.path.abspath(path)

        result = []
        for root, dirs, files in os.walk(path):
            exclude = "Archive", "Test"
            dirs[:] = [d for d in dirs if d not in exclude]
            if all(subdir in dirs for subdir in subdirs):
                    result.append(root)
        return result

    except WindowsError:
        pass
def get_directory_listing(path):
    try:
        output = {}
        output["text"] = path.decode('latin1')
        output["type"] = "directory"
        output["children"] = all_dirs_with_subdirs("G:\TEST", ('Maps', 'Temp'))
        return output

    except WindowsError:
        pass
with open(r'G:\JSONData.json', 'w+') as f:
    listing = get_directory_listing("G:\TEST")
    json.dump(listing, f)

2 个答案:

答案 0 :(得分:0)

您只有一个级别的层次结构,因为在all_dirs_with_dubdirs中,您遍历目录树并将每个有效目录附加到平面列表result,然后将其存储在唯一的"children"密钥中

您要做的是创建一个像

这样的结构
{
  'text': 'root_dir',
  'type': 'directory',
  'children': [
     {
       'text': 'subdir1 name',
       'type': 'directory',
       'children': [
         {
           'text': 'subsubdir1.1 name',
           'type': 'directory',
           'children': [
             ...
           ]
         },
         ...
       ]
     },
     {
       'text': 'subdir2 name',
       'type': 'directory',
       'children': [
         ...
       ]
     },
  ]
}

你可以通过递归非常优雅地做到这一点

def is_valid_dir(path, subdirs):
    return all(os.path.isdir(path) for subdir in subdirs)


def all_dirs_with_subdirs(path, subdirs):
    children = []

    for name in os.listdir(path):
        subpath = os.path.join(path, name)
        if name not in ("Archive", "Test") and os.path.isdir(subpath) and is_valid_dir(subpath, subdirs):
            children.append({
                'text': name,
                'type': 'directory',
                'children': all_dirs_with_subdirs(subpath, subdirs)
            })

    return children

答案 1 :(得分:0)

您可以通过以下方式获得CWD的直接孩子:

next(os.walk('.'))[1]

使用该表达式,您可以编写一个递归遍历函数,如下所示:

def dir_to_json(dir):
    subdirs = next(os.walk('dir'))[1]
    if not subdirs:
        return # Something in your base case, how are you representing this?
    return combine_as_json(dir_to_json(os.path.join(dir, d)) for d in subdirs)

然后你需要创建一个combine_as_json()函数来聚合你选择的编码/表示中的子目标结果。