Пользовательское сопоставление файлов Python JSON для пользовательских - PullRequest
0 голосов
/ 19 ноября 2018

Недавно я создал парсер в Python 3, который преобразует файлы из пользовательского формата (назовем формат .querty) в JSON (.json) для более удобного управления его содержимым. Теперь мне интересно, как лучше всего перевести обратно JSON в мой исходный формат, сохранив всю его первоначальную структуру.

Пример файлов можно увидеть ниже,

example.qwerty

Dict_abc_1{

    Dict_abc_2{
        HeaderGUID="";
        Version_TPI="999";
        EncryptionType="0";
    }

    Dict_abc_3{
        FamilyName="John Doe";
    }

    Dict_abc_4{
        Array_abc{
            {TimeStamp="2018-11-07 01:00:00"; otherinfo="";}
            {TimeStamp="2018-11-07 01:00:00"; otherinfo="";}
            {TimeStamp="2018-11-07 01:00:00"; otherinfo="";}
            {TimeStamp="2018-11-07 02:53:57"; otherinfo="";}
            {TimeStamp="2018-11-07 02:53:57"; otherinfo="";}
        }

        Dict_abc_5{
            LastContact="2018-11-08 01:00:00";
            BatteryStatus=99;
            BUStatus=PowerOn;
            LastCallTime="2018-11-08 01:12:46";
            LastSuccessPoll="2018-11-08 01:12:46";
            CallResult=Successful;
        }
    }
}
Code=999999;

example.json

{  
    "Dict_abc_1":{
        "Dict_abc_2":{
            "HeaderGUID":"",
            "Version_TPI":"999",
            "EncryptionType":"0"
        },

        "Dict_abc_3":{
            "FamilyName":"John Doe"
        },

        "Dict_abc_4":{
            "Array_abc":[
                {"TimeStamp":"2018-11-07 01:00:00", "otherinfo":""},
                {"TimeStamp":"2018-11-07 01:00:00", "otherinfo":""},
                {"TimeStamp":"2018-11-07 01:00:00", "otherinfo":""},
                {"TimeStamp":"2018-11-07 02:53:57", "otherinfo":""},
                {"TimeStamp":"2018-11-07 02:53:57", "otherinfo":""}
            ],

            "Dict_abc_5":{
                "LastContact":"2018-11-08 01:00:00",
                "BatteryStatus":99,
                "BUStatus":"PowerOn",
                "LastCallTime":"2018-11-08 01:12:46",
                "LastSuccessPoll":"2018-11-08 01:12:46",
                "CallResult":"Successful"
            }
        }
    },
    "Code":999999
}

Структурные определения .qwerty, которые отличаются от json

  • Словари / Массивы не имеют разделений между ними и их ключом
  • Словари / массивы имеют два перевода строки после определения
  • Переменные используют '=' в качестве разделителя между ними и их значением
  • Переменные используют ';' после их значения
  • Массивы используют {} вместо []

Поскольку мой текущий парсер .qwerty to .json использует лексический и синтаксический анализ. Я не думаю, что необходимо воссоздавать другой синтаксический анализатор, используя этот метод, поскольку данные теперь находятся в очень удобной форме (json). Мне было интересно, будет ли хорошей идеей расширить json.dumps для адаптации к моим новым определениям, но я не знаю, с чего начать или возможно ли это.

Я пытаюсь сделать это эффективно, мысли и подходы очень ценятся, спасибо.

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Я думаю, это сработало бы грубо, хотя я не проверял его. Одна заметная трудность может быть связана со списками, так как этот фрагмент кода не будет работать, если списки могут содержать что-либо кроме dicts. Возможно, вам придется адаптировать эту часть кода - или, если содержимое dict внутри списка не обязательно должно быть все в одной строке, вы также можете сделать это рекурсивным. Но, надеюсь, это хорошее начало для экспериментов.

Это рекурсивная функция. Три входа: словарь для анализа, файл для записи и текущий уровень отступа.

def print_qwerty(json_dict, file_descriptor, indent_level=0):
    for (k, v) in json_dict.items():
        if type(v) == dict:
            file_descriptor.write('    '*indent_level + k + '{\n')
            print_qwerty(v, file_descriptor, indent_level + 1)
            file_descriptor.write('    '*indent_level + ';}\n')
        elif type(v) == list:
            for i in v:
                args_str = ['{}="{}"'.format(k2,v2) for (k2, v2) in i.items()]
                file_descriptor.write('    '*indent_level + '{' + '; '.join(args_str) + '}\n')
        else:
             file_descriptor.write('    '*indent_level + '{}="{}";\n'.format(k, v))

Пример использования:

import json
with open('example.json', 'r') as json_file:
    json_dict = json.loads(json_file.read())
with open('example.qwerty', 'w') as 'qwerty_file':
    print_qwerty(json_dict, qwerty_file)
0 голосов
/ 19 ноября 2018

Поскольку ваш синтаксис выглядит относительно простым, вы можете избежать использования лексического и синтаксического анализа.Вместо этого вы можете использовать некоторые регулярные выражения для распознавания ваших массивов / словарей и переменных и просто соответствующим образом изменить форматирование с помощью простой замены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...