2010-07-16 76 views
0

我想將平面表單數據轉換爲python或javascript中的遞歸JSON數據。這個JSON數據稍後可以通過模板引擎解釋(谷歌的暴風雨,它有django喜歡的語法)。有很多示例將平面數據轉換爲遞歸數據,但問題是它不能是字典或列表。HTML表單數據遞歸json字典

我試圖用很多方式做,但沒有成功。所以,在我至少拖了兩個星期後,我決定在這裏提出一個問題。

的FORMDATA是這樣的(鍵名稱可能不同):

formdata = [ 
    {"formname": "name", "formvalue": "Roel Kramer"}, 
    {"formname": "email", "formvalue": "[email protected]"}, 
    {"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": "[email protected]"} 

總腳本可以在github gist看到。我知道它可以更清潔,但當它工作時我會重構它。

我在做什麼錯?我完全錯過了什麼嗎? 非常感謝!

回答

1

好吧,如果你知道的格式將是一致的,然後像這將工作:

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. The。字符將樹中的節點分開,並始終遵循索引號。
  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

+0

非常感謝埃裏克!這真的幫了我。評論使一切變得清晰。我也不知道{} .setdefault。 我不能爲你投票..必須先建立一個聲望。 – 2010-07-17 11:40:22

+0

我很高興能幫到你!你仍然可以接受答案。只需點擊投票箭頭下的複選標記即可。 – 2010-07-17 15:28:56