如何排除某种"类型的树节点"来自JSON反序列化

时间:2018-01-12 06:13:17

标签: c# json serialization tree json.net

假设我有一个字符串格式的节点树,我将其命名为stringTree,其中包含我认为不必要的type: "Category"节点,如下所示:

{
    Id: 1,
    Type: "Product",
    Children: [
                  {
                      Id: 1.1,
                      Type: "Product",
                      Children: [
                                    {
                                        Id: 1.1.1,
                                        Type: "Category",
                                        Children: null
                                    },
                                    {
                                        Id: 1.1.2,
                                        Type: "Product",
                                        Children: null
                                    }
                                ]
                  },
                  {
                      Id: 1.2,
                      Type: "Category",
                      Children: null
                  }
              ]
}

请注意,这些不必要的节点可以位于树的任何级别。

我有一个包含我的树的大字符串,我将使用JsonConvert反序列化,如下所示:

var myTree = JsonConvert.Deserialize<Tree>(treeString);

有没有一种方法可以让反序列化忽略任何节点(及其子节点),如果它们有type = "Category"?基本上意味着这个树将在反序列化后从节点1.2和1.1.1中修剪出来。

2 个答案:

答案 0 :(得分:0)

您可以使用自定义反序列化器实现此目的,但更简单的方法是将输入字符串解析为JToken s树并过滤掉代表具有Type == "Category"的对象的标记:

var jToken = JToken.Parse(treeString);
FilterTree(jToken);
Console.WriteLine(JsonConvert.SerializeObject(jToken, Formatting.Indented));

// ..................

static void FilterTree(JToken jToken)
{
    var jArr = jToken as JArray;
    if (jArr != null)
        for (int i = jArr.Count - 1; i >= 0; i--)
        {
            if ((string)jArr[i]["Type"] == "Category")
                jArr[i].Remove();
        }
    foreach (var child in jToken.Children())
        FilterTree(child);
}

演示:https://dotnetfiddle.net/HjVngF

答案 1 :(得分:0)

是否要求在反序列化过程中完成过滤?如果没有,您可以向Tree类添加一个简短的递归方法,以过滤掉不需要的节点作为后处理步骤:

public Tree Filter(string typeToRemove)
{
    if (Type == typeToRemove)
        return null;

    if (Children != null)
        Children = Children.Select(c => c.Filter(typeToRemove))
                           .Where(c => c != null)
                           .ToList();
    return this;
}

然后像这样使用它:

var tree = JsonConvert.DeserializeObject<Tree>(json)?.Filter("Category");

小提琴:https://dotnetfiddle.net/NrvUZn