skip to Main Content

I am trying to make changes to an C# based opensource json editor which has MIT license. I want to remove the items like ({object}, {Array}) from the Json tree view. here is the link to the Open source Json Editor and here is the link (Clicking on this link will download the JSON-EDITOR)to a editor which i used as a reference for Expected output.

Test.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
                }
            }
        ]
    }
}

Current Output
Open Source editors current output

Like shown in the images below i want to remove elements marked with red to make it look like the image on the right

Expected Output
enter image description here

There are 2 projects inside in the solution JsonEditor and JsonTreeview. There is a function called AfterExpand() in all these files enter image description here
I’m sure that function is responsible for displaying those unwanted items. so i made the Text string empty in all the files this function is present so the items will be gone.

 /// <inheritdoc />
        public override void AfterExpand()
        {
            base.AfterExpand();

            Text = $@"[{JArrayTag.Type}]";
// change i made 
            Text = "";
        }

but it seems there are empty spaces being displayed now. Any help would be really appreciated. Thanks in advance.

enter image description here

4

Answers


  1. To remove the items like ({object}, {Array}) from the JSON tree view in C#, you can create a recursive function that traverses the JSON data and removes the nodes that are of type "Object" or "Array". Here’s an example implementation:

    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);
            }
        }
    }
    
    Login or Signup to reply.
  2. Your current solution is not actually modifying the structure of the tree, it is only modifying the text of the nodes that represent object or array.

    I understand why you are wanting to do what you want to do: make the tree more compact, and, perhaps, more visually appealing. But, that leads to a loss in "fidelity". Not having the {object} and {array} nodes removes information about what the value of the property actually is: an object or an array (an answer to another question explains it in a bit more detail).

    This will force your users to take on the cognitive burden of knowing implicitly that, for example, JSON is an object because the nodes underneath it are just named properties, and that ANIMALS in an array because the nodes underneath it are indexed [0], [1] and so on.

    This is happening at "tree build time" not during the "tree visualization" step. These two bits of code (1, 2)…

    1. Create and return a TreeNode that is associated with either a JToken that’s either a JObject or a JArray, which they are. Those are the tokens for {} (object) and [] (array) respectively.
    2. Which at visualization time, render as a single TreeNode with the text {object} or [array].

    If you’re ok with the cognitive burden, you need to change the referenced code to return an IEnumerable<TreeNode> instead of a single TreeNode.

    Modifying JsonTreeNodeFactory.cs like so

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

    would do this, but you have to change the call sites to add the enumerable of nodes to the tree (e.g. with AddRange() instead of the single add with Add().

    NOTE: The above code is not tested, but it should at least be enough pseudo-code to give you the gist of what to do.

    If you do this, you have to contend with exporting this back to JSON. Somehow you have to "invisibly store" the real context — that the missing node is an object or an array.

    I leave that part to you.

    Login or Signup to reply.
  3. JObject json = JObject.Parse(jsonString);
    
    // Convert the JObject to a TreeNode
    TreeNode rootNode = ConvertToTreeNode(json);
    
    // Remove invalid nodes from the tree
    RemoveInvalidNodes(rootNode);
    
    // Set the TreeView control's root node
    treeView1.Nodes.Clear();
    treeView1.Nodes.Add(rootNode);
    -----------------------------------------------
        private void RemoveInvalidNodes(TreeNode node)
        {
            for (int i = node.Nodes.Count - 1; i >= 0; i--)
            {
                TreeNode childNode = node.Nodes[i];
        
                if (childNode.Nodes.Count > 0)
                {
                    RemoveInvalidNodes(childNode);
        
                    if (childNode.Nodes.Count == 0)
                    {
                        node.Nodes.Remove(childNode);
                    }
                }
                else if (childNode.Text == "[]" || childNode.Text == "{}")
                {
                    node.Nodes.Remove(childNode);
                }
            }
        }
        In this example, we first parse the JSON string into a JObject using JObject.Parse(). We then convert the JObject to a TreeNode using the ConvertToTreeNode() method, which recursively iterates over the JSON tree and creates a corresponding TreeNode for each object a`enter code here`nd array.
        
        We then use the RemoveInvalidNodes() method to remove any nodes that do not contain valid JSON data. 
    
    Login or Signup to reply.
  4. Like shown in the images below i want to remove elements marked with red to make it look like the image on the right

    Currently Json Editor is using JTokenTreeView, which is based on Treeview component. To make it show like the image, you need to modify the code to add the node to TreeView, mainly in JsonTreeNodeFactory.cs

    1. Modify TreeNode Create(JProperty obj, int depth) function in JsonTreeNodeFactory.cs
    public static TreeNode Create(JProperty obj, int depth)
    {
        var node = new JPropertyTreeNode(obj);
    
        if (depth != 1)
        {
            int remainingDepth = (depth == UnlimitedDepth ? UnlimitedDepth : depth - 1);
            foreach(dynamic o in obj) {
                if (o is JObject) CreateObject(node, o, remainingDepth);
                else if (o is JArray) CreateArray(node, o, remainingDepth);
                else if (o is JValue) continue;
                else node.Nodes.Add(Create((dynamic)o, remainingDepth));
            }
        }
    
        return node;
    }
    
    1. Add 2 missing function
    public static void CreateArray(TreeNode parent, JArray obj, int depth)
    {
        var node = parent ?? new JArrayTreeNode(obj);
    
        if (depth != 1)
        {
            int remainingDepth = (depth == UnlimitedDepth ? UnlimitedDepth : depth - 1);
            node.Nodes.AddRange(obj
                .Select(o => Create((dynamic)o, remainingDepth))
                .Cast<TreeNode>()
                .ToArray()
                );
        }
    }
    
    public static void CreateObject(TreeNode parent, JObject obj, int depth)
    {
        var node = parent ?? new JObjectTreeNode(obj);
    
        if (depth != 1)
        {
            int remainingDepth = (depth == UnlimitedDepth ? UnlimitedDepth : depth - 1);
            node.Nodes.AddRange(obj.Properties()
                .Select(o => Create(o, remainingDepth))
                .ToArray()
                );
        }
    }
    
    1. Modify private static void ExpandTreeNodeDepth(JTokenTreeNode node) in JTokenTreeNode.cs
    private static void ExpandTreeNodeDepth(JTokenTreeNode node)
    {
        if (node.Nodes.Count > 0)
        {
            foreach (JTokenTreeNode childNode in node.Nodes)
            {
                ExpandTreeNodeDepth(childNode);
            }
        }
        else
        {
            foreach (var jToken in node.JTokenTag)
            {
                // Modify is this line
                if (node.JTokenTag is JProperty && jToken is JValue)
                    continue;
                node.Nodes.Add(JsonTreeNodeFactory.Create(jToken, 1));
            }
        }
    }
    

    The main idea is that: Do not create JObject or JArray node if it’s a value of a property. Do not create child JValue node of JProperty.

    Please be noted that, this code is not full-featured for your question yet. But, you can continue to update for your need:

    • Check the root node and set it’s name as ‘root’ (instead of {Object})
    • Base on position of element in object/array to show [index] when collapse/expand

    NOTE: because we change the element in treeview, the Json Editor may not work as before

    Hope this helps!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search