假设我有一个字符串格式的节点树,我将其命名为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中修剪出来。
答案 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);
}
答案 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");