2012-07-27 85 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