是否可以使用JSON.NET从JSON对象中删除JSON对象?

时间:2015-06-01 14:21:05

标签: c# .net json json.net

我可以在JSON.NET中合并JSON对象,但是;

我想从JSON对象中删除JSON对象,如下所示:

{
"name":"Mike",
"surname":"Dow",
"children":["James","John"],
"data":{"A1":"B1","A2":"B2","A3":"B3"},
"data2":{"A1":"B1","A2":"B2","A3":"B3","A4":"B4"},
"data3":{"A1":{"B1":"C1","B2":"C2"}}
}

减去

{
"name":"Mike",
"children":["James"],
"data":{"A1":"B1"},
"data2":{"A3":"B3","A4":"B4"},
"data3":{"A1":{"B2":"C2"}}
}

等于

{
"surname":"Dow",
"children":["John"],
"data":{"A2":"B2","A3":"B3"},
"data2":{"A1":"B1","A2":"B2"},
"data3":{"A1":{"B1":"C1"}}
}

JSON.NET可以吗?

1 个答案:

答案 0 :(得分:0)

您没有指定如何处理数组匹配。如果您只是匹配数组索引,那么您可以将JToken.SelectTokenJToken.Path结合使用,以匹配减数中的值与minuend中的值:

        var minuend = JToken.Parse(minuendJson);
        var subtrahend = JToken.Parse(subtrahendJson);
        foreach (var toRemove in subtrahend.DescendantsAndSelf().OfType<JValue>().Select(t => minuend.SelectToken(t.Path)).Where(t => t != null).ToList())
            toRemove.RemoveFromLowestPossibleParent();

使用扩展方法:

public static class JsonExtensions
{
    public static void RemoveFromLowestPossibleParent(this JToken node)
    {
        if (node == null)
            throw new ArgumentNullException();
        var contained = node.AncestorsAndSelf().Where(t => t.Parent is JArray || t.Parent is JObject).FirstOrDefault();
        if (contained != null)
            contained.Remove();
    }

    public static IEnumerable<JToken> DescendantsAndSelf(this JToken node)
    {
        if (node == null)
            return Enumerable.Empty<JToken>();
        var container = node as JContainer;
        if (container != null)
            return container.DescendantsAndSelf();
        else
            return new [] { node };
    }
}

如果你想匹配&#34; leaf&#34;数组值按值而不是索引,你可以这样做:

public static class JsonExtensions
{
    public static JToken MatchToken(this JToken target, JToken source)
    {
        var sourceArray = source.Parent as JArray;
        if (sourceArray != null)
        {
            var targetArray = target.SelectToken(sourceArray.Path) as JArray;
            if (targetArray != null)
            {
                // There may be duplicated values in the source and target arrays. If so, get the relative index of the
                // incoming value in the list of duplicates in the source, and return the corresponding value in the list
                // of duplicates in the target.
                var sourceIndices = Enumerable.Range(0, sourceArray.Count).Where(i => JToken.DeepEquals(sourceArray[i], source)).ToList();
                var targetIndices = Enumerable.Range(0, targetArray.Count).Where(i => JToken.DeepEquals(targetArray[i], source)).ToList();
                var matchIndex = sourceIndices.IndexOf(sourceArray.IndexOf(source));
                Debug.Assert(matchIndex >= 0);// Should be found inside its parent.
                if (matchIndex >= 0 && matchIndex < targetIndices.Count)
                    return targetArray[targetIndices[matchIndex]];
                return null;
            }
        }

        return target.SelectToken(source.Path);
    }
}

然后

        var minuend = JToken.Parse(minuendJson);
        var subtrahend = JToken.Parse(subtrahendJson);
        foreach (var toRemove in subtrahend.DescendantsAndSelf().OfType<JValue>().Select(t => minuend.MatchToken(t)).Where(t => t != null).ToList())
            toRemove.RemoveFromLowestPossibleParent();