如何在javascript中解析json字符串包含循环引用?

时间:2021-04-08 19:03:13

I have the following json string in javascript. This string contains a circular references. I want to parse this string in such a way that the reference will be replaced by its actual object. I use Json.Parse but it creates the json object with references. Is there any way by whihc i can achieve this ?

我在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
    }
  ]
} 

3 个解决方案

#1


3  

This should do it:

这应该这样做:

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;
}            

#2


1  

You should check out Douglas Crockfords JSON-js repo on github: https://github.com/douglascrockford/JSON-js

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

There's a cycle.js in there that helps you do exactly what you're looking for.

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

#3


0  

Look at my post here, I've found some bugs in the code above and there wasn't arrays support, check out my improved version: Resolve circular references from JSON object

看看我的帖子,我在上面的代码中发现了一些错误并且没有数组支持,请查看我的改进版本:解决JSON对象的循环引用

#1


3  

This should do it:

这应该这样做:

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;
}            

#2


1  

You should check out Douglas Crockfords JSON-js repo on github: https://github.com/douglascrockford/JSON-js

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

There's a cycle.js in there that helps you do exactly what you're looking for.

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

#3


0  

Look at my post here, I've found some bugs in the code above and there wasn't arrays support, check out my improved version: Resolve circular references from JSON object

看看我的帖子,我在上面的代码中发现了一些错误并且没有数组支持,请查看我的改进版本:解决JSON对象的循环引用