我有一个包含types
列表的JSON。这些类型有一些名称和某些字段。
字段具有dataType
的属性,如果其值为object
,则表示另一种类型。可以通过在referenceType
属性中指定的名称来找到该类型。
还有一个名为parentType
的属性,这意味着该类型是parentType的子级,它包含一些其他属性,但仅应视为parentType
的对象。
我正在尝试处理此JSON,以获取数组中所有类型的所有嵌套属性名称。
{
"types": [
{
"name": "User1",
"fields": [
{
"name": "name",
"dataType": "string"
},
{
"name": "address",
"dataType": "object",
"referenceType": "Address",
"isArray": true
},
{
"name": "weeklyRoles",
"dataType": "object",
"isArray": true,
"referenceType": "Role"
}
]
},
{
"name": "User2",
"fields": [
{
"name": "name",
"dataType": "string"
},
{
"name": "address",
"dataType": "object",
"referenceType": "Address",
"isArray": true
}
]
},
{
"name": "Address",
"fields": [
{
"name": "AddressLine1",
"dataType": "string"
},
{
"name": "AddressLine2",
"dataType": "string"
}
]
},
{
"name": "BusinessAddress",
"parentType": "Address",
"fields": [
{
"name": "headquarters",
"dataType": "string"
}
]
},
{
"name": "ServiceAddress",
"parentType": "Address",
"fields": [
{
"name": "servicePartner",
"dataType": "string"
},
{
"name": "serviceType",
"dataType": "string"
}
]
},
{
"name": "Role",
"fields": [
{
"name": "roleName",
"dataType": "string"
},
{
"name": "accessCountsObj1",
"dataType": "object",
"referenceType": "Role2"
}
]
},
{
"name": "Role2",
"fields": [
{
"name": "roleName2",
"dataType": "string"
},
{
"name": "accessCountsObj2",
"dataType": "object",
"referenceType": "Role3"
}
]
},
{
"name": "Role3",
"fields": [
{
"name": "roleName3",
"dataType": "string"
},
{
"name": "accessCountsObj3",
"dataType": "object",
"referenceType": "Role4"
}
]
},
{
"name": "Role4",
"fields": [
{
"name": "roleName4",
"dataType": "string"
}
]
}
]
}
我期望结果为<typeName>;<fieldName>.<nestedFieldName>
预期产量
[
"User1;address.AddressLine1",
"User1;address.AddressLine2",
"User1;address.headquarters",
"User1;address.servicePartner",
"User1;address.serviceType",
"User1;weeklyRoles.roleName",
"User1;weeklyRoles.accessCountsObj1.roleName2",
"User1;weeklyRoles.accessCountsObj1.accessCountsObj2.roleName3",
"User1;weeklyRoles.accessCountsObj1.accessCountsObj2.accessCountsObj3.roleName4",
"User2;address.AddressLine1",
"User2;address.AddressLine2",
"User2;address.headquarters",
"User2;address.servicePartner",
"User2;address.serviceType",
"Role;accessCountsObj1.roleName2",
"Role;accessCountsObj1.accessCountsObj2.roleName3",
"Role;accessCountsObj1.accessCountsObj2.accessCountsObj3.roleName4",
"Role2;accessCountsObj2.roleName3",
"Role2;accessCountsObj2.accessCountsObj3.roleName4",
]
我试图编写一个递归函数来处理它,但是它没有给我预期的结果,也没有终止条件。
public IList<string> GetKeys(JArray types, string parentType = null)
{
var nestedKeys = new List<string>();
foreach (var type in types)
{
var fields = type[Constants.Fields].ToObject<List<JObject>>();
var typeName = type.Value<string>("name");
var nestedKeyBuilder = new StringBuilder($"{typeName};");
if (!string.IsNullOrEmpty(parentType))
{
nestedKeyBuilder = new StringBuilder($"{parentType};");
}
foreach (var field in fields)
{
var datatype = field.Value<string>("dataType");
if (string.Equals(datatype,"object"))
{
var fieldName = field.Value<string>("name");
var referenceTypeName = field.Value<string>("referenceType");
var referenceTypeObject = types.Where(t => string.Equals(t.Value<string>("name"), referenceTypeName))?.First();
if (referenceTypeObject != null)
{
var refTypeFields = referenceTypeObject["fields"].ToObject<List<JObject>>();
foreach (var refTypeField in refTypeFields)
{
var refTypeFieldName = refTypeField.Value<string>("name");
var refTypeDataType = refTypeField.Value<string>("dataType");
var refTypeReferenceTypeName = refTypeField.Value<string>("referenceType");
if (string.Equals(refTypeDataType, "object") && string.Equals(refTypeReferenceTypeName, currentReferenceType))
{
var refTypeNestedKeys = GetKeys(types, typeName);
nestedKeys.AddRange(refTypeNestedKeys);
}
else
{
nestedKeyBuilder.Append($"{fieldName}.{refTypeFieldName}");
nestedKeys.Add(nestedKeyBuilder.ToString());
}
}
}
}
}
}
return nestedKeys;
}
答案 0 :(得分:0)
答案 1 :(得分:0)
使用newtonsoft JSON反序列化JSON字符串。
JSON.Deserialize<IEnumberable<Type>>(jsonString);
这应该给您一个IEnumerable来处理它,但是您可以使用它。类型是您使用JSON属性作为类属性创建的类。您可以使用类似的东西
注意:“类型”和“字段”是非常模糊的名称。 Type是一个c#类,因此您不应使用它来创建自己的类。您将面临模棱两可的错误,并且需要完全限定名称空间才能使用您的类。强烈建议使用其他名称,并使用属性将其映射到JSON字符串。
[JsonObject(Title="People")]
public class Type
{
[JsonProperty("name")]
string Name{ get; set; }
[JsonProperty("fields")]
Field FieldValue[]{ get; set; }
}
答案 2 :(得分:0)
您可以使用Newtonsoft
库执行此操作。
这是您的POCO课。
{
public string name { get; set; }
public string dataType { get; set; }
public string referenceType { get; set; }
public bool? isArray { get; set; }
}
public class Type
{
public string name { get; set; }
public List<Field> fields { get; set; }
public string parentType { get; set; }
}
public class RootObject
{
public List<Type> types { get; set; }
}
并将函数写入DeserializeObject
[TestMethod]
public void Read()
{
var sample1 = @"X:\JsonFilePath\data.json";
var jsonString=File.ReadAllText(sample1);
var result =JsonConvert.DeserializeObject<RootObject>(jsonString);
Assert.IsNotNull(result);
}