2013-02-27 43 views
4

我在JavaScript中有以下json字符串。该字符串包含循环引用。我想以这样一种方式解析这个字符串,即引用将被它的实际对象所取代。我使用Json.Parse,但它使用引用创建json对象。有什么办法可以实现这一目标吗?如何解析json字符串在javascript中包含循环引用?

{ 
    "$id": "1", 
    "$values": [ 
    { 
     "$id": "2", 
     "Event": { 
     "$id": "3", 
     "Invitaions": { 
      "$id": "4", 
      "$values": [ 
      { 
       "$ref": "2" 
      }, 
      { 
       "$id": "5", 
       "Event": { 
       "$ref": "3" 
       }, 
       "Id": 2, 
       "Name": "test2", 
       "Date": "24", 
       "EventId": 1 
      } 
      ] 
     }, 
     "Id": 1, 
     "Name": "marriage", 
     "Address": "abcd" 
     }, 
     "Id": 1, 
     "Name": "test1", 
     "Date": "23", 
     "EventId": 1 
    }, 
    { 
     "$ref": "5" 
    }, 
    { 
     "$id": "6", 
     "Event": { 
     "$id": "7", 
     "Invitaions": { 
      "$id": "8", 
      "$values": [ 
      { 
       "$ref": "6" 
      } 
      ] 
     }, 
     "Id": 2, 
     "Name": "birthday", 
     "Address": "abcd" 
     }, 
     "Id": 3, 
     "Name": "test3", 
     "Date": "25", 
     "EventId": 2 
    } 
    ] 
} 
+4

JavaScript本身或jQuery中没有预先烘焙过。您必须编写它(或找到某人已经编写的插件/脚本来执行此操作)。非常简单,可以通过'parse'返回的对象图并通过查找'$ ref'属性进行循环并替换它们。 – 2013-02-27 17:45:31

+1

你有没有试过这个插件:https://code.google.com/p/jquery-json/? – 2013-02-27 17:58:14

+0

构建了带有循环引用的JSON是什么,该工具不提供JavaScript解析功能? – Bergi 2013-02-27 20:08:42

回答

3

这应做到:

function resolveReferences(json) { 
    if (typeof json === 'string') 
     json = JSON.parse(json); 

    var byid = {}, // all objects by id 
     refs = []; // references to objects that could not be resolved 
    json = (function recurse(obj, prop, parent) { 
     if (typeof obj !== 'object' || !obj) // a primitive value 
      return obj; 
     if ("$ref" in obj) { // a reference 
      var ref = obj.$ref; 
      if (ref in byid) 
       return byid[ref]; 
      // else we have to make it lazy: 
      refs.push([parent, prop, ref]); 
      return; 
     } else if ("$id" in obj) { 
      var id = obj.$id; 
      delete obj.$id; 
      if ("$values" in obj) // an array 
       obj = obj.$values.map(recurse); 
      else // a plain object 
       for (var prop in obj) 
        obj[prop] = recurse(obj[prop], prop, obj) 
      byid[id] = obj; 
     } 
     return obj; 
    })(json); // run it! 

    for (var i=0; i<refs.length; i++) { // resolve previously unknown references 
     var ref = refs[i]; 
     ref[0][ref[1]] = byid[refs[2]]; 
     // Notice that this throws if you put in a reference at top-level 
    } 
    return json; 
}