Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON.NET how to remove nodes

Tags:

I have a json like the following:

{   "d": {     "results": [       {         "__metadata": {         },         "prop1": "value1",         "prop2": "value2",         "__some": "value"       },       {         "__metadata": {         },         "prop3": "value1",         "prop4": "value2",         "__some": "value"       },     ]   } } 

I just want to transform this JSON into a different JSON. I want to strip out the "_metadata" and "_some" nodes from the JSON. I'm using JSON.NET.

like image 773
Mohamed Nuur Avatar asked Jul 26 '12 18:07

Mohamed Nuur


People also ask

How to remove node from JSON?

You can use the JSON Remove Node filter to remove a JSON node from a JSON message. You can specify the node to remove using a JSON Path expression. The JSON Path query language enables you to select nodes in a JSON document. For more details on JSON Path, see http://code.google.com/p/jsonpath.

How to remove in JSON?

To remove JSON element, use the delete keyword in JavaScript.

What is JToken in C#?

JToken is the abstract base class of JObject , JArray , JProperty , and JValue , which represent pieces of JSON data after they have been parsed. JsonToken is an enum that is used by JsonReader and JsonWriter to indicate which type of token is being read or written.


2 Answers

I just ended up deserializing to JObject and recursively looping through that to remove unwanted fields. Here's the function for those interested.

private void removeFields(JToken token, string[] fields) {     JContainer container = token as JContainer;     if (container == null) return;      List<JToken> removeList = new List<JToken>();     foreach (JToken el in container.Children())     {         JProperty p = el as JProperty;         if (p != null && fields.Contains(p.Name))         {             removeList.Add(el);         }         removeFields(el, fields);     }      foreach (JToken el in removeList)     {         el.Remove();     } } 
like image 166
Mohamed Nuur Avatar answered Dec 14 '22 19:12

Mohamed Nuur


Building off of @[Mohamed Nuur]'s answer, I changed it to an extension method which I think works better:

 public static JToken RemoveFields(this JToken token, string[] fields)     {         JContainer container = token as JContainer;         if (container == null) return token;          List<JToken> removeList = new List<JToken>();         foreach (JToken el in container.Children())         {             JProperty p = el as JProperty;             if (p != null && fields.Contains(p.Name))             {                 removeList.Add(el);             }             el.RemoveFields(fields);         }          foreach (JToken el in removeList)         {             el.Remove();         }          return token;     } 

Here is unit test:

[TestMethod]      public void can_remove_json_field_removeFields()      {         string original = "{\"d\":{\"results\":[{\"__metadata\":{},\"remove\":\"done\",\"prop1\":\"value1\",\"prop2\":\"value2\",\"__some\":\"value\"},{\"__metadata\":{},\"prop3\":\"value1\",\"prop4\":\"value2\",\"__some\":\"value\"}],\"__metadata\":{\"prop3\":\"value1\",\"prop4\":\"value2\"}}}";         string expected = "{\"d\":{\"results\":[{\"prop1\":\"value1\",\"prop2\":\"value2\",\"__some\":\"value\"},{\"prop3\":\"value1\",\"prop4\":\"value2\",\"__some\":\"value\"}]}}";         string actual = JToken.Parse(original).RemoveFields(new string[]{"__metadata", "remove"}).ToString(Newtonsoft.Json.Formatting.None);         Assert.AreEqual(expected, actual);      } 
like image 25
Rafi Avatar answered Dec 14 '22 19:12

Rafi