2012-07-26 11 views
13

Mam json tak:JSON.NET jak usunąć węzły

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

po prostu chcesz przekształcić ten JSON do innego JSON. Chcę usunąć "JAON" z węzłów "_ " i " _some". Używam JSON.NET.

+1

Nie mam doświadczenia z C#, ale zakładam, że możesz po prostu parsować JSON, skasować klucze z wynikowej struktury danych i przekonwertować ją ponownie na JSON. –

+0

Mogę to zrobić, ale szukałem sposobu, żeby to zrobić JSON.NET. –

Odpowiedz

25

Właśnie skończyłem deserializing na JObject i rekursywnie przechodząc przez to, aby usunąć niechciane pola. Oto funkcja dla zainteresowanych.

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

Dzięki! Potrzebowałem tego. Teraz mogę zrobić Foreach w mojej kolekcji JArray's Children, aby usunąć wszystkie moje właściwości, które chcę. – duyn9uyen

+0

To mi naprawdę pomogło - chciałem zalogować dane JSON z wrażliwymi polami zastąpionymi przez długość danych. Udało mi się uzyskać i ustawić wartość p.Value. – 79IT

2

Utworzę nową strukturę danych z wymaganymi informacjami i skopiuję dane z pierwszej. Często jest to najprostsze podejście. Tylko pomysł.

+1

Ale nie wiem, jakie dane będą. Chcę napisać ogólną funkcję, która zajmie ciąg JSON i listę właściwości do wykluczenia (może xpath type?) I zwróci nowy ciąg JSON bez właściwości, które są wykluczone. –

9

budynku off @ [Mohamed Nuur] 's odpowiedź, zmieniłem go na metodę rozszerzenia, które moim zdaniem działa lepiej:

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

Oto testy jednostkowe:

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