5

我在 javascript 中有以下 json 字符串。此字符串包含循环引用。我想以引用将被其实际对象替换的方式解析此字符串。我使用Json.Parse,但它创建带有引用的 json 对象。有什么办法可以做到这一点吗?

{
  "$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

3 回答 3

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;
}            
于 2013-02-27T20:51:09.510 回答
1

你应该在 github 上查看 Douglas Crockfords JSON-js repo:https ://github.com/douglascrockford/JSON-js

那里有一个 cycle.js 可以帮助你做你正在寻找的东西。

于 2013-02-27T20:03:39.923 回答
0

看看我的帖子,我在上面的代码中发现了一些错误,并且没有数组支持,请查看我的改进版本:Resolve circular references from JSON object

于 2013-04-02T06:29:30.667 回答