【问题标题】:Is it possible to remove JSON object from JSON object with JSON.NET?是否可以使用 JSON.NET 从 JSON 对象中删除 JSON 对象?
【发布时间】:2015-06-01 14:21:04
【问题描述】:

我可以在 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 可以吗?

【问题讨论】:

  • 不是重复的。我不想删除一个属性数组,而是一个 json。我想要 JTokens 的区别。
  • 这正是另一篇文章中所做的,只是需要在您的最后进行一些自定义!!!
  • 你想如何处理数组?按索引匹配?

标签: c# .net json json.net


【解决方案1】:

您没有指定要如何处理数组匹配。如果您只是简单地匹配数组索引,那么您可以将JToken.SelectTokenJToken.Path 结合起来,以匹配被减数中的值和被减数中的值:

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

如果你想通过值而不是索引来匹配“叶”数组值,你可以这样做:

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();

【讨论】:

    猜你喜欢
    • 2018-07-30
    • 1970-01-01
    • 2019-02-01
    • 2022-10-17
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    相关资源
    最近更新 更多