假设我有一个字符串格式的节点树,我将其命名为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 中修剪出来。
您可以使用自定义反序列化程序来实现此目的,但更简单的方法是将输入字符串解析为 JToken
的树,并过滤掉表示对象的标记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
是否要求在反序列化过程中进行筛选? 如果没有,您可以在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