0

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

rohith santosh
  • 28
  • 6
  • 23
DeLorean
  • 186
  • 13
  • Can you post the code you use to create the three view from json? – Serge Feb 14 '23 at 21:26
  • @Serge, As mentioned in the question above here is the link : https://github.com/zetoken/JSon-Editor to the whole project. here you will find "JsonTreeView" folder which contains the all the logic to convert json to treeview. – DeLorean Feb 15 '23 at 02:23
  • 2
    this file in specific contains the logic for getting nodes " master\JsonTreeView\JsonTreeNodeFactory.cs " – DeLorean Feb 15 '23 at 09:11
  • 1
    Don't include links that ultimately include an executable in the download. Even if benign, this is how malware starts. – Kit Feb 22 '23 at 22:53
  • Might you please [edit] your question to add enough code to reproduce the problem **in the question itself**? As explained in [Something in my web site or project doesn't work. Can I just paste a link to it?](https://meta.stackoverflow.com/q/254428), questions asking for help with off-site code are off topic for Stack Overflow. If you need help trimming your code down for the question, [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) can help. – dbc Mar 03 '23 at 16:14
  • Hi thanks for the suggestion. but i have already added the links to the repository. its where all of the code is present. Also i mentioned the change i made. – DeLorean Mar 08 '23 at 07:54
  • Please let me know if you need anything else from me. – DeLorean Mar 08 '23 at 14:04

4 Answers4

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.

Kit
  • 20,354
  • 4
  • 60
  • 103
0

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!

binhgreat
  • 982
  • 8
  • 13
-1
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. 
Bhupatsinh
  • 36
  • 2
-2

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);
        }
    }
}
Bhupatsinh
  • 36
  • 2