JSON.NET как удалить узлы

У меня есть такой json:

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

Я просто хочу преобразовать этот JSON в другой JSON. Я хочу удалить узлы «_ метаданные» и « _some» из JSON. Я использую JSON.NET.


person Mohamed Nuur    schedule 26.07.2012    source источник
comment
У меня нет опыта работы с C #, но я предполагаю, что вы можете просто проанализировать JSON, удалить их ключи из полученной структуры данных и снова преобразовать ее обратно в JSON.   -  person Felix Kling    schedule 26.07.2012
comment
Я могу это сделать, но я искал способ сделать это с помощью JSON.NET.   -  person Mohamed Nuur    schedule 26.07.2012


Ответы (4)


Я просто закончил десериализацию в JObject и рекурсивно перебирал его, чтобы удалить ненужные поля. Вот функция для желающих.

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();
    }
}
person Mohamed Nuur    schedule 26.07.2012
comment
Спасибо! Мне это было нужно. Теперь я могу выполнить Foreach в моей коллекции JArray's Children, чтобы удалить все нужные мне свойства. - person duyn9uyen; 15.11.2013
comment
Это действительно помогло мне - я хотел регистрировать данные JSON с заменой конфиденциальных полей на длину данных. Мне удалось получить и установить p.Value. - person 79IT; 12.07.2014

Основываясь на ответе @ [Mohamed Nuur], я изменил его на метод расширения, который, как мне кажется, работает лучше:

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

Вот модульный тест:

[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);
     }
person Rafi    schedule 23.07.2015
comment
отличное решение, проверенное и использованное - person Johann Medina; 26.12.2019

Я бы создал новую структуру данных только с необходимой информацией и скопировал бы данные из первой. Часто это самый простой подход. Просто идея.

person Anders Lindén    schedule 26.07.2012
comment
Но я не знаю, какие будут данные. Я хочу написать общую функцию, которая будет принимать строку JSON и список исключаемых свойств (возможно, тип xpath?) И возвращать новую строку JSON без исключаемых свойств. - person Mohamed Nuur; 27.07.2012

Этот ответ применим, если у вас есть JArray с JTokens, а не JObjects:

Вот пример:

string json = "[null, null, \"x\", null, null, null, 0,[],[[\"x\"], null,[0],[\"x\"]]]";

    JArray array = JArray.Parse(json);

    // Keep first 3 elements, remove the rest
    int max = array.Count;
    for (int i = 0; i < max - 3; i++)
    {
        JToken elem = array[3];
        array.Remove(elem);
    }

    json = array.ToString(Newtonsoft.Json.Formatting.None);

    Console.WriteLine(json);
person live-love    schedule 18.04.2020