Данные формы HTML в рекурсивном формате JSON - PullRequest
0 голосов
/ 16 июля 2010

Я хотел бы преобразовать данные плоской формы в рекурсивные данные JSON на python или javascript.Эти данные JSON могут быть позже интерпретированы с помощью шаблонизатора (Google для Tempest, имеет синтаксис django).Существует множество примеров преобразования плоских данных в рекурсивные, но проблема в том, что это не может быть только дикт или список.

Я пытался сделать это разными способами, но пока не получилось.Поэтому, почесав голову в течение как минимум двух недель, я решил задать вопрос здесь.

Форма данных такая (имена ключей могут отличаться):

formdata = [
    {"formname": "name", "formvalue": "Roel Kramer"},
    {"formname": "email", "formvalue": "blaat@blaat.nl"},
    {"formname": "paragraph-0.title", "formvalue": "test titel 1"},
    {"formname": "paragraph-0.body", "formvalue": "bla bla body 1"},
    {"formname": "paragraph-0.image-0.src", "formvalue": "src 1"},
    {"formname": "paragraph-0.image-1.src", "formvalue": "src 2"},
    {"formname": "paragraph-1.title", "formvalue": "test titel 2"},
    {"formname": "paragraph-1.body", "formvalue": "bla bla body 2"},
    {"formname": "paragraph-1.image-0.src", "formvalue": "src 3"},
    {"formname": "paragraph-1.image-1.src", "formvalue": "src 4"},
    {"formname": "paragraph-1.image-2.src", "formvalue": "src 5"},
    {"formname": "paragraph-2.title", "formvalue": "test titel 3"},
    {"formname": "paragraph-2.body", "formvalue": "bla bla body 3"},
    {"formname": "paragraph-2.image-0.src", "formvalue": "src 6"},
    {"formname": "paragraph-2.image-1.src", "formvalue": "src 7"},
]

Я бы хотелчтобы преобразовать его в этот формат:

{'paragraph':
    [
        {
        'image': [{'src': 'src 1'}, {'src': 'src 2'}],
        'body': 'body 2',
        'title': 'titel 2'
        },
        {
        'image': [{'src': 'src 3'}, {'src': 'src 4'}, {'src': 'src 5'}],
        'body': 'body 2',
        'title': 'titel 2'
        },
        {
        'image': [{'src': 'src 6'}, {'src': 'src 7'},
        'body': 'body 3',
        'title': 'titel 3'
        },
    ],
}

Как вы видите, я смешиваю диктанты со списками, что делает его немного сложнее.В своей последней попытке я дошел до того, что сценарий выяснил, где добавлять списки и где добавлять диктанты.Это приводит к следующему:

{'paragraph': [{'image': []}, {'image': []}, {'image': []}]}

Но когда я добавляю данные, результат не тот, который я ожидал.

{"paragraph": [{"body": "bla bla body 1", "image": {"src": "src 7"}, "title": "test titel 1"}, {"body": "bla bla body 2", "image": {"src": "src 5"}, "title": "test titel 2"}, {"body": "bla bla body 3", "image": {"src": "src 3"}, "title": "test titel 3"}, {"image": {"src": "src 6"}}], "name": "Roel Kramer", "email": "contact@roelkramer.nl"}

Полный сценарий можно увидеть на github gist .Я знаю, что это может быть намного чище, но я сделаю рефакторинг, когда он будет работать.

Что я делаю не так?Я что-то пропустил?Большое спасибо!

1 Ответ

1 голос
/ 16 июля 2010

Ну, если вы знаете, что формат будет согласованным, то будет работать примерно так:

def add_data(node, name, value):
    if '-' not in name:
        node[name] = value
    else:
        key = name[:name.index('-')]
        node_index = int(name[len(key) + 1:name.index('.')])
        node.setdefault(key, [])
        if node_index >= len(node[key]):
            node[key].append({})
        add_data(node[key][node_index],
                 name[name.index('.') + 1:],
                 value)

Затем, чтобы использовать его, просто сделайте что-то вроде этого:

root_node = {}
for data in formdata:
    add_data(root_node, data['formname'], data['formvalue'])

Функция делает следующие предположения:

  1. Символ - используется для указания узла определенного типа, за которым следует по номеру.
  2. . символ разделяет узлы в дереве и всегда следует за порядковым номером.
  3. Данные формы всегда будут идти по порядку. (абзац-0, абзац-1, абзац-2) вместо (абзац-1, абзац-0, абзац-3).

Итак, вот код с комментариями, объясняющими это:

def add_data(node, name, value):
    # We're at a parent node (ex: paragraph-0), so we need to drill down until
    # we find a leaf node
    if '-' in name:
        key = name[:name.index('-')]
        node_index = int(name[len(key) + 1:name.index('.')])

        # Initialize the parent node if needed by giving it a dict to store it's
        # information nodes
        node.setdefault(key, [])
        if node_index >= len(node[key]):
            node[key].append({})

        # Drill down the tree by calling this function again, making this
        # parent node the root
        add_data(node[key][node_index],
                 name[name.index('.') + 1:],
                 value)

    # We're at a leaf node, so just add it to the parent node's information
    # ex:  The first formdata item would make the root_node dict look like
    # { 'name': 'Roel Kramer' }
    else:
        node[name] = value

Вот рабочий пример: http://pastebin.com/wpMPXs1r

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