Python中的TreeView到JSON

2024-09-29 17:13:40 发布

您现在位置:Python中文网/ 问答频道 /正文

[编辑:显然此文件类似于h5格式] 我正在尝试使用Python中的hyperspy从扩展名为(.dm3)的文件中提取元数据,我能够获取所有数据,但它被保存在树视图中,但我需要Json中的数据。我尝试使用自己的解析器对其进行转换,这在大多数情况下都有效,但失败了:

TreeView image

TreeView data generated

是否有一个库或包可以用来在Pyton中将treeview转换为JSON

我的解析器:

def writearray(file,string):
    k = string.split('=')
    file.write('"' + k[0] + '":' + '[')
    for char in k[1]:
        file.write(char)
    file.write(']')

def writenum(file,string):
    k = string.split('=')
    file.write('"' + k[0] + '":' + k[1])

def writestr(file,string):
    k = string.split('=')
    file.write('"' + k[0] + '":' +'"'+ k[1]+'"')

def startnew(file,string):
    file.write('"'+string+'":'+'{\n')

def closenum(file,string):
    k = string.split('=')
    file.write('"' + k[0] + '":' + k[1] + '\n')
    file.write('},\n')

def closestr(file,string):
    k = string.split('=')
    file.write('"' + k[0] + '":' + '"' + k[1] + '"' + '\n')
    file.write('},\n')

def closearr(file,string):
    k = string.split('=')
    file.write('"' + k[0] + '":' + '[')
    for char in k[1]:
        file.write(char)
    file.write(']\n')
    file.write('},\n')

def strfix(string):
    temp = ''
    for char in string:
        if char != ' ':
            temp += char
    return temp

def writethis(file,string):
    stripped = strfix(string)
    if "=" in stripped:
        temp = stripped.split("=")
        if ',' in temp[1]:
            writearray(file,stripped)
        elif temp[1].isdigit() or temp[1].isdecimal():
            writenum(file,stripped)
        else:
            writestr(file,stripped)

def createMetaData(dm3file):
    txtfile = os.path.splitext(dm3file)[0] + '.txt'
    jsonfile = os.path.splitext(dm3file)[0] + '.json'
    s = hs.load(dm3file)
    s.original_metadata.export(txtfile)
    file1 = open(txtfile, 'r', encoding="utf-8")
    Lines = file1.readlines()
    k = []
    for line in Lines:
        k.append(line)
    L = []
    for string in k:
        temp = ''
        for char in string:
            if char.isalpha() or char.isdigit() or char == '=' or char == ' ' or char == '<' or char == '>' or char == ',' or char == '.' or char == '-' or char == ':':
                temp += char
        L.append(temp)
    file2 = open(jsonfile, 'w', encoding="utf-8")
    file2.write('{\n')
    for i in range(0, len(L) - 1):
        currentspaces = len(L[i]) - len(L[i].lstrip())
        nextspaces = len(L[i + 1]) - len(L[i + 1].lstrip())
        sub = nextspaces - currentspaces
        if i != len(L) - 2:
            if (sub == 0):
                writethis(file2, L[i])
                if '=' in L[i]:
                    file2.write(',\n')
                else:
                    file2.write('\n')
            elif sub > 0:
                startnew(file2, L[i])
            else:
                if sub == -3:
                    writethis(file2, L[i])
                    file2.write('\n},\n')
                elif sub == -7:
                    writethis(file2, L[i])
                    file2.write('\n}\n},\n')
        else:
            writethis(file2, L[i])
            file2.write('\n}\n}\n}\n}')
    file1.close()
    os.remove(txtfile)
enter code here

Tags: orinforstringlenifdeftemp
1条回答
网友
1楼 · 发布于 2024-09-29 17:13:40

我为树状视图格式编写了一个解析器:

from ast import literal_eval
from collections import abc
from more_itertools import peekable


def parse_literal(x: str):
    try:
        return literal_eval(x)
    except Exception:
        return x.strip()


def _treeview_parse_list(lines: peekable) -> list:
    list_as_dict = {}
    for line in (x.strip() for x in lines):
        raw_k, raw_v = line.split(' = ')
        list_as_dict[int(raw_k.split()[-1][1:-1])] = parse_literal(raw_v)
        peek = lines.peek(None)
        if '╚' in line or (peek is not None and '├' in peek):
            break
    list_as_list = [None] * (max(list_as_dict) + 1)
    for idx, v in list_as_dict.items():
        list_as_list[idx] = v
    return list_as_list


def _treeview_parse_dict(lines: peekable) -> dict:
    node = {}
    for line in (x.strip() for x in lines):
        if ' = ' in line:
            raw_k, raw_v = line.split(' = ')
            node[raw_k.split()[-1]] = parse_literal(raw_v)
        elif '<list>' in line:
            node[line.split()[-2]] = _treeview_parse_list(lines)
        else:
            try:
                idx = line.index('├')
            except ValueError:
                idx = line.index('└')
            peek = lines.peek(None)
            if peek is not None and '├' in peek and idx == peek.index('├'):
                node[line.split()[-1]] = {}
            else:
                node[line.split()[-1]] = _treeview_parse_dict(lines)
        if '└' in line:
            break
    return node


def treeview_to_dict(lines: abc.Iterable) -> dict:
    return _treeview_parse_dict(peekable(lines))

用法:

with open('meta.txt') as f:
    d = treeview_to_dict(f)

您可以使用Python的内置json库以JSON文件的形式获取元数据:

import json

with open('meta.txt') as txt_file:
    with open('meta.json', 'w') as json_file:
        json.dump(treeview_to_dict(txt_file), json_file, indent=4)

我添加了indent=4以使JSON文件更具可读性,以便您可以对照原始格式进行验证。据我所知,他们以一种合理的方式匹配

正如我所写的,它使用第三方^{}类。如果您不能使用more_itertools,那么您自己实现该功能应该不会太难,或者只是重构代码,这样就不必再向前看了


License

这是发布到公共领域的免费无障碍软件。

任何人都可以自由复制、修改、发布、使用、编译、销售或 以源代码形式或编译后的格式分发此软件 二进制,出于任何目的,商业或非商业,以及 意思是说。

在承认版权法的司法管辖区内,本软件的作者将本软件的任何和所有版权权益专用于公共领域。我们作出这一奉献是为了广大公众的利益,也是为了我们的继承人和继承人的利益 继任者。我们希望这一奉献是一种公开的行动 永久放弃本协议的所有现有和未来权利 版权法下的软件。

软件按“原样”提供,无任何形式的担保, 明示或暗示,包括但不限于 适销性、适用于特定目的和侵权。在任何情况下,作者均不对任何索赔、损害赔偿或其他责任承担责任,无论是合同诉讼、侵权诉讼还是其他诉讼,均由本软件或本软件的使用或其他交易引起或与之相关。

有关更多信息,请参阅https://unlicense.org

相关问题 更多 >

    热门问题