2009-07-31 158 views
5

對於使用JSON(而不是XML)我相當新,目前我純粹使用Javascript來消化,解析和顯示返回的JSON數據。使用Javascript將嵌套JSON轉換爲HTML嵌套列表

我使用的JSON2.js庫和我找回代表一個相當簡單的嵌套列表中的某些有效的JSON數據:

{ 
    "node":{ 
    "class":"folder", 
    "title":"Test Framework", 
    "node":{ 
     "class":"folder", 
     "title":"Item 1", 
     "node":{ 
     "class":"folder", 
     "title":"Item 1.1", 
     "node":{ 
      "class":"file", 
      "title":"Item 1.1.a" 
     } 
     }, 
     "node":{ 
     "class":"folder", 
     "title":"Item 1.2", 
     "node":{ 
      "class":"file", 
      "title":"Item 1.2.a" 
     }, 
     "node":{ 
      "class":"file", 
      "title":"Item 1.2.b" 
     }, 
     "node":{ 
      "class":"file", 
      "title":"Item 1.2.c" 
     } 
     }, 
     "node":{ 
     "class":"folder", 
     "title":"Item 1.3", 
     "node":{ 
      "class":"folder", 
      "title":"Item 1.3.a", 
      "node":{ 
      "class":"file", 
      "title":"Item 1.3.a.i" 
      }, 
      "node":{ 
      "class":"file", 
      "title":"Item 1.3.a.ii" 
      } 
     } 
     } 
    }, 
    "node":{ 
     "class":"folder", 
     "title":"Item 2", 
     "node":{ 
     "class":"file", 
     "title":"item 2.a" 
     }, 
     "node":{ 
     "class":"file", 
     "title":"Item 2.b" 
     } 
    } 
    } 
} 

有沒有人有一個快速的方法的指針把該批次成UL與所有的嵌套元素?如果JSON中的「class」元素可以用作每個LI的類,那也很酷。

任何幫助,非常感謝。

謝謝,

戴夫。

+0

FWIW:我認爲你的JSON有問題。有幾個地方你在同一個對象中有多個「節點」鍵。 – 2009-07-31 10:36:22

回答

9

您的json不適合您的任務。一些對象具有多個名稱相同的屬性(「節點」),因此它們互相重疊。您必須改用節點數組。這是一個有效的數據結構,可以把它變成一個嵌套列表的功能:

<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01//EN" 
    "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
<title></title> 
<script type="text/javascript"> 
function parseNodes(nodes) { // takes a nodes array and turns it into a <ol> 
    var ol = document.createElement("OL"); 
    for(var i=0; i<nodes.length; i++) { 
     ol.appendChild(parseNode(nodes[i])); 
    } 
    return ol; 
} 

function parseNode(node) { // takes a node object and turns it into a <li> 
    var li = document.createElement("LI"); 
    li.innerHTML = node.title; 
    li.className = node.class; 
    if(node.nodes) li.appendChild(parseNodes(node.nodes)); 
    return li; 
} 

window.jsonData = [{ 
    "class": "folder", 
    "title": "Test Framework", 
    "nodes": [{ 
     "class": "folder", 
     "title": "Item 1", 
     "nodes": [{ 
      "class": "folder", 
      "title": "Item 1.1", 
      "nodes": [{ 
       "class": "file", 
       "title": "Item 1.1.a" 
      }] 
     }, 
     { 
      "class": "folder", 
      "title": "Item 1.2", 
      "nodes": [{ 
       "class": "file", 
       "title": "Item 1.2.a" 
      }, 
      { 
       "class": "file", 
       "title": "Item 1.2.b" 
      }, 
      { 
       "class": "file", 
       "title": "Item 1.2.c" 
      }] 
     }, 
     { 
      "class": "folder", 
      "title": "Item 1.3", 
      "nodes": [{ 
       "class": "folder", 
       "title": "Item 1.3.a", 
       "nodes": [{ 
        "class": "file", 
        "title": "Item 1.3.a.i" 
       }, 
       { 
        "class": "file", 
        "title": "Item 1.3.a.ii" 
       }] 
      }] 
     }] 
    }, 
    { 
     "class": "folder", 
     "title": "Item 2", 
     "nodes": [{ 
      "class": "file", 
      "title": "item 2.a" 
     }, 
     { 
      "class": "file", 
      "title": "Item 2.b" 
     }] 
    }] 
}]; 

</script> 
</head> 
<body> 
    <input type="button" 
    onclick="document.body.appendChild(parseNodes(jsonData))" 
    value="go" /> 
</body> 
</html> 

而且我可以添加這個CSS有numberings匹配節點標題:)

<style type="text/css"> 
ol { list-style-type: none } 
ol ol { list-style-type: decimal } 
ol ol ol { list-style-type: decimal } 
ol ol ol ol { list-style-type: lower-alpha } 
ol ol ol ol ol { list-style-type: lower-roman } 
</style> 

See it in action.項目

0

您可以自己瀏覽您的json結構,並在需要時創建適當的<li>,但我建議您實施複合模式。有關更多詳細信息,請參閱link

1

下面是一些相當簡單的代碼,它爲每個對象創建一個<ul>元素,併爲每個部分創建一個<li>元素。如果您想添加特殊情況,您可以添加一個快速檢查來測試child變量,如"class"

function jsonToHtmlList(json) { 
    return objToHtmlList(JSON.parse(json)); 
} 

function objToHtmlList(obj) { 
    if (obj instanceof Array) { 
     var ol = document.createElement('ol'); 
     for (var child in obj) { 
      var li = document.createElement('li'); 
      li.appendChild(objToHtmlList(obj[child])); 
      ol.appendChild(li); 
     } 
     return ol; 
    } 
    else if (obj instanceof Object && !(obj instanceof String)) { 
     var ul = document.createElement('ul'); 
     for (var child in obj) { 
      var li = document.createElement('li'); 
      li.appendChild(document.createTextNode(child + ": ")); 
      li.appendChild(objToHtmlList(obj[child])); 
      ul.appendChild(li); 
     } 
     return ul; 
    } 
    else { 
     return document.createTextNode(obj); 
    } 
} 

這不會做你想要的,因爲你的JSON沒有意義。 JavaScript中的對象(因此是JSON)是地圖,因此不能有多個具有相同名稱的子項。正如Cédric指出的那樣,您需要將多個「節點」變成一個數組。