2012-07-27 83 views
8

我有一個字符串表示JSON,我想用JSON.NET重命名一些屬性。我需要一個通用函數來用於任何JSON。類似於:Json.net重命名屬性

public static void Rename(JContainer container, Dictiontionary<string, string> mapping) 
{ 
    foreach (JToken el in container.Children()) 
    { 
    JProperty p = el as JProperty; 
    if(el != null && mapping.ContainsKey(p.Name)) 
    { 
     // **RENAME THIS NODE!!** 
    } 

    // recursively rename nodes 
    JContainer pcont = el as JContainer; 
    if(pcont != null) 
    { 
     Rename(pcont, mapping); 
    } 
    } 
} 

怎麼辦?

回答

13

我建議用更名的屬性重建你的JSON。我不認爲你應該擔心速度處罰,因爲這通常不是問題。這是你如何做到的。

public static JToken Rename(JToken json, Dictionary<string, string> map) 
{ 
    return Rename(json, name => map.ContainsKey(name) ? map[name] : name); 
} 

public static JToken Rename(JToken json, Func<string, string> map) 
{ 
    JProperty prop = json as JProperty; 
    if (prop != null) 
    { 
     return new JProperty(map(prop.Name), Rename(prop.Value, map)); 
    } 

    JArray arr = json as JArray; 
    if (arr != null) 
    { 
     var cont = arr.Select(el => Rename(el, map)); 
     return new JArray(cont); 
    } 

    JObject o = json as JObject; 
    if (o != null) 
    { 
     var cont = o.Properties().Select(el => Rename(el, map)); 
     return new JObject(cont); 
    } 

    return json; 
} 

下面是使用的例子:

var s = @"{ ""A"": { ""B"": 1, ""Test"": ""123"", ""C"": { ""Test"": [ ""1"", ""2"", ""3"" ] } } }"; 
var json = JObject.Parse(s); 

var renamed = Rename(json, name => name == "Test" ? "TestRenamed" : name); 
renamed.ToString().Dump(); // LINQPad output 

var dict = new Dictionary<string, string> { { "Test", "TestRenamed"} }; 
var renamedDict = Rename(json, dict); 
renamedDict.ToString().Dump(); // LINQPad output 
+0

梅德感謝,這是完美的! – 2012-07-27 21:26:54

+0

可以有一些小錯誤,但你可以自己修復它們,如果你發現任何:) – 2012-07-28 10:37:23

3

我們使用這種方法。你可以使用JObject的SelectToken()找到你想要的屬性。是的,它支持JsonPath。

public static class NewtonsoftExtensions 
{ 
    public static void Rename(this JToken token, string newName) 
    { 
     var parent = token.Parent; 
     if (parent == null) 
      throw new InvalidOperationException("The parent is missing."); 
     var newToken = new JProperty(newName, token); 
     parent.Replace(newToken); 
    } 
} 
+0

有點驚訝,你沒有指出,這實際上是框架的一部分,由你降落:https://github.com/abibell /Newtonsoft.Json/commit/12f3f32401074a84b3d186956e59e56c9e8781cb :-) – 2016-03-17 10:27:54

+0

嗨阿拉斯泰爾,我想要的功能。我爲它做了咖啡更改併發送了拉取請求。它不是用理性的擁有者必須接受「我不喜歡它」 .https://github.com/JamesNK/Newtonsoft.Json/pull/549 – 2016-03-18 19:37:16

+1

@AbiBellamkonda,我想使用這個擴展的方法重命名JProperty對象,但我得到異常「無法將Newtonsoft.Json.Linq.JProperty添加到Newtonsoft.Json.Linq.JProperty。」從這一段代碼:'new JProperty(newName,token)'。 – Gyromite 2017-04-18 18:33:23