Json.NET 中对象的层次结构可能相当深。可以在以下位置找到粗略指南:这个答案 https://stackoverflow.com/questions/20532567/json-net-confusion-in-getting-parent-from-jtoken/20532778#20532778.
要解决您的问题,您首先需要一个扩展方法来获取 a 的属性JObject
然后返回带有名称前缀的集合:
public static class JsonExtensions
{
public static IEnumerable<KeyValuePair<string, JToken>> FlattenFields(this JObject obj, string prefix)
{
foreach (var field in obj)
{
string fieldName = prefix + "_" + field.Key;
var fieldValue = field.Value;
yield return new KeyValuePair<string, JToken>(fieldName, fieldValue);
}
}
}
接下来,您需要一些递归工具来迭代 Json.NET 层次结构并重写所选属性的集合JObject
's:
public static class JsonExtensions
{
public static IEnumerable<T> Yield<T>(this T item)
{
yield return item;
}
public static JToken EditFields(this JToken token, Func<KeyValuePair<string, JToken>, IEnumerable<KeyValuePair<string, JToken>>> editor)
{
if (token == null)
return null;
switch (token.Type)
{
case JTokenType.Array:
return EditFields((JArray)token, editor);
case JTokenType.Object:
return EditFields((JObject)token, editor);
default:
return token;
}
}
static JToken EditFields(JArray array, Func<KeyValuePair<string, JToken>, IEnumerable<KeyValuePair<string, JToken>>> editor)
{
JArray newArray = null;
foreach (var element in array)
{
var newElement = EditFields(element, editor);
if (newElement != null)
{
if (newArray == null)
newArray = new JArray();
newArray.Add(newElement);
}
}
return newArray;
}
static JToken EditFields(JObject obj, Func<KeyValuePair<string, JToken>, IEnumerable<KeyValuePair<string, JToken>>> editor)
{
JObject newObj = null;
foreach (var field in obj)
{
foreach (var newField in editor(field))
{
if (newObj == null)
newObj = new JObject();
newObj[newField.Key] = newField.Value.EditFields(editor);
}
}
return newObj;
}
}
最后,将它们放在一起创建一个方法来提升命名的属性JObject
其父母的财产JObject
,在属性名称前面加上下划线:
public static class JsonExtensions
{
public static JToken PromoteNamedPropertiesToParents(this JToken token, string propertyName)
{
return token.EditFields(pair =>
{
if (pair.Key == propertyName && pair.Value is JObject)
{
return ((JObject)pair.Value).FlattenFields(pair.Key);
}
return pair.Yield();
});
}
}
然后,进行测试:
public static class TestFlatten
{
public static void Test()
{
string jsonString = @"{
""data"": [
{
""company"": {
""ID"": ""12345"",
""location"": ""Some Location""
},
""name"": ""Some Name""
}
]
}";
JObject obj = JObject.Parse(jsonString);
var newObj = (JObject)obj.PromoteNamedPropertiesToParents("company");
Debug.WriteLine(newObj);
}
}
输出是:
{
"data": [
{
"company_ID": "12345",
"company_location": "Some Location",
"name": "Some Name"
}
]
}
这就是你想要的。请注意,此代码创建了一个新的JObject
层次结构而不是修改原始层次结构。