我试图通过递归遍历将嵌套的json转换为简单的json。 (输入json的结构未知)
例如,我想要像这样的json
{
"FirstName": "Rahul",
"LastName": "B",
"EmpType": {
"RID": 2,
"Title": "Full Time"
},
"CTC": "3.5",
"Exp": "1",
"ComplexObj": {
"RID": 3,
"Title": {
"Test": "RID",
"TWO": {
"Test": 12
}
}
}
}
要转换成这样的东西
{
"FirstName": "Rahul",
"LastName": "B",
"EmpType__RID": 2,
"EmpType__Title": "Full Time",
"CTC": "3.5",
"Exp": "1",
"ComplexObj__RID": 3,
"ComplexObj__Title__Test": "RID",
"ComplexObj__Title__TWO__Test": 12
}
嵌套对象中的每个字段都将更改为表示其实际路径的键。
这是我到目前为止所做的。
public static void ConvertNestedJsonToSimpleJson(JObject jobject, ref JObject jobjectRef, string currentNodeName = "", string rootPath = "")
{
string propName = "";
if (currentNodeName.Equals(rootPath))
{
propName = currentNodeName;
}
else
{
propName = (rootPath == "" && currentNodeName == "") ? rootPath + "" + currentNodeName : rootPath + "__" + currentNodeName;
}
foreach (JProperty jprop in jobject.Properties())
{
if (jprop.Children<JObject>().Count() == 0)
{
jobjectRef.Add(propName == "" ? jprop.Name : propName + "__" + jprop.Name, jprop.Value);
}
else
{
currentNodeName = jprop.Name;
rootPath = rootPath == "" ? jprop.Name : rootPath;
ConvertNestedJsonToSimpleJson(JObject.Parse(jprop.Value.ToString()), ref jobjectRef, currentNodeName, rootPath);
}
}
}
并得出错误的结果
{
"FirstName": "Rahul",
"LastName": "B",
"EmpType__RID": 2,
"EmpType__Title": "Full Time",
"CTC": "3.5",
"Exp": "1",
"EmpType__ComplexObj__RID": 3,
"EmpType__Title__Test": "RID",
"EmpType__two__Test": 12
}
非常感谢有关更正我的代码或任何其他归档方法的帮助。
答案 0 :(得分:5)
JObject
prefix + jprop.Name + "__"
代码:
public static void FlattenJson(JObject node, JObject result, string prefix = "")
{
foreach (var jprop in node.Properties())
{
if (jprop.Children<JObject>().Count() == 0)
{
result.Add(prefix + jprop.Name, jprop.Value);
}
else
{
FlattenJson((JObject)jprop.Value, $"{prefix}{jprop.Name}__", result);
}
}
}
您可以这样称呼它:
var node = JObject.Parse(/* the input string */);
var result = new JObject();
FlattenJson(node, result);
答案 1 :(得分:4)
您的问题在rootPath = rootPath == "" ? jprop.Name : rootPath;
行。当您第一次遇到EmpType
时,您正在更改rootPath,这意味着当您处理ComplexObj
时,您的rootPath是错误的。我相信你的目的只是改变你传递给递归函数的内容。
尽管没有必要将root和currentnode跟踪为两个单独的项目。更好的方法是在代码中跟踪给定节点的当前前缀,看起来更像这样:
public static void ConvertNestedJsonToSimpleJson(JObject input, JObject output, string prefix = "")
{
foreach (JProperty jprop in input.Properties())
{
var name = prefix==""?jprop.Name:String.Format("{0}__{1}", prefix,jprop.Name);
if (jprop.Children<JObject>().Count() == 0)
{
output.Add(name, jprop.Value);
}
else
{
ConvertNestedJsonToSimpleJson((JObject)jprop.Value, output, name);
}
}
}
这现在给我输出:
{
"FirstName": "Rahul",
"LastName": "B",
"EmpType__RID": 2,
"EmpType__Title": "Full Time",
"CTC": "3.5",
"Exp": "1",
"ComplexObj__RID": 3,
"ComplexObj__Title__Test": "RID",
"ComplexObj__Title__TWO__Test": 12
}
看起来是正确的。
答案 2 :(得分:1)
你能用linq做这样的事吗
var jsonObj = jobject.select(x => new CustomJson {
FirstName = x.FirstName,
LastName = x.LastName,
EmpTypeId = x.EmpType.Id,
Title = x.EmpType.Title
etc etc
});