我正在尝试更改具有 MIT 许可的基于 C# 的开源 json 编辑器。我想从 Json 树视图中删除 ({object}, {Array}) 之类的项目。这是开源 Json 编辑器的链接,这是我用作预期输出参考的编辑器的链接。
测试.json
{
"TEST JSON" : "JSON",
"JSON":{
"ANIMALS":[
{
"ID":0,
"TYPE":"DOG",
"DOG":{
"TYPE":"RETRIEVER",
"RETRIEVER":{
"NAME":"LEO",
"AGE":3,
"YEARS":[2019 , 2020, 2021],
"WEIGHTS": [2,10,13]
}
},
"REMARKS":{
"ID":1,
"STATUS":"GOOD",
"REFERENCE": {
"SOURCE": "XYZ",
"FIT": 1,
"BMI" : 1
}
}
},
{
"ID":1,
"TYPE":"DOG2",
"DOG2":{
"TYPE":"PUG",
"RETRIEVER":{
"NAME":"HUTCH",
"AGE":4,
"YEARS":[2019 , 2020, 2021, 2022],
"WEIGHTS": [2,3,4,4]
}
},
"REMARKS":{
"ID":1,
"TYPE" : "REFERENCE",
"STATUS":"OK",
"REFERENCE": {
"SOURCE": "XYZ",
"FIT": 1,
"BMI" : 1
}
}
},
{
"ID": 2,
"TYPE": "DIAGNOSTICS",
"STATUS": "ENABLED"
},
{
"ID": 3,
"TYPE": "ORGANISATION",
"ORGANISATION":{
"NAME":"RED CROSS",
"YEAR": 2023
}
}
]
}
}
如下图所示,我想删除标有红色的元素,使其看起来像右图
解决方案里面有2个工程JsonEditor和JsonTreeview。所有这些文件中都有一个名为 AfterExpand() 的函数 我确定该功能负责显示那些不需要的项目。所以我在所有存在此功能的文件中将文本字符串设为空,这样项目就会消失。
/// <inheritdoc />
public override void AfterExpand()
{
base.AfterExpand();
Text = $@"[{JArrayTag.Type}]";
// change i made
Text = "";
}
但是现在显示的似乎是空白。任何帮助将非常感激。提前致谢。
要从 C# 中的 JSON 树视图中删除 ({object}, {Array}) 等项目,您可以创建一个递归函数来遍历 JSON 数据并删除类型为“Object”或“Array”的节点。这是一个示例实现:
using Newtonsoft.Json.Linq;
public void RemoveObjectAndArrayNodes(JToken node)
{
if (node.Type == JTokenType.Object || node.Type == JTokenType.Array)
{
node.Replace(new JObject());
}
else
{
foreach (var child in node.Children())
{
RemoveObjectAndArrayNodes(child);
}
}
}
您当前的解决方案实际上并没有修改树的结构,它只是修改了代表对象或数组的节点的文本。
我明白为什么你想做你想做的事:让树更紧凑,也许更视觉吸引力。但是,这会导致“保真度”的损失。没有
{object}
和 {array}
节点会删除有关属性值实际是什么的信息:对象或数组(an answer to another question explained bit more detailed it)。
这将迫使您的用户承担隐式知道的认知负担,例如,
JSON
是一个对象,因为它下面的节点只是命名属性,而ANIMALS
在数组中,因为它下面的节点是索引[0]
,[1]
等等。
这是在“树构建时间”而不是在“树可视化”步骤中发生的。这两位代码(1,2)...
TreeNode
,它与一个 JToken
相关联,它是一个 JObject
或一个 JArray
,它们是。这些分别是{}
(对象)和[]
(数组)的标记。TreeNode
和文本 {object}
或 [array]
.如果您可以接受认知负担,则需要更改引用代码以返回一个
IEnumerable<TreeNode>
而不是单个 TreeNode
。
public static IEnumerable<TreeNode> Create(JArray obj, int depth)
{
// don't need this anymore
// var node = new JArrayTreeNode(obj);
if (depth != 1)
{
int remainingDepth = (depth == UnlimitedDepth ? UnlimitedDepth : depth - 1);
return obj
.Select(o => Create((dynamic)o, remainingDepth))
.Cast<TreeNode>()
.ToArray();
}
return Array.Empty<TreeNode>();
}
public static IEnumerable<TreeNode> Create(JObject obj, int depth)
{
// don't need this anymore
// var node = new JObjectTreeNode(obj);
if (depth != 1)
{
int remainingDepth = (depth == UnlimitedDepth ? UnlimitedDepth : depth - 1);
return obj.Properties()
.Select(o => Create(o, remainingDepth))
.ToArray();
}
return Array.Empty<TreeNode>();
}
会这样做,但是您必须更改调用站点以将节点的可枚举添加到树中(例如,使用
AddRange()
而不是使用 Add()
的单个添加。
注意: 上面的代码是未测试的,但它至少应该是足够的伪代码来给你做什么的要点。
如果你这样做,你必须努力将其导出回 JSON。您必须以某种方式“不可见地存储”real 上下文——丢失的节点是一个对象或数组。
我把那部分留给你。