识别 属性 的值是一个数组
Identifying that a property's value is an array
我有一个 JSON 文件:
{
"abn":"63119059513",
"acn":"119059513",
"business_structure":"Private Company",
"ngr_number":"1231231",
"cbh_number":"1231231",
"main_name":"Brickworks Building Products Pty Ltd",
"trading_name":"Brickworks",
"other_trading_names":"Austral Bricks",
"directors":[
{
"ID":"12114",
"ae_forms_filled_in_ID":"22739",
"name":"John Smith",
"dob":"1983-10-29",
"address_line_1":"123 Fake Street",
"address_line_2":"",
"address_line_city":"Fakeland",
"address_line_postcode":"2000",
"address_line_state":"New South Wales",
"address_line_country":"Australia",
"order_extract_id":null,
"director_found":null,
"drivers_lic":"",
"home_mortgage":"",
"phone":"",
"mobile":"",
"director_email":"",
"director_title":"Mr",
"director_position":"Director",
"dir_pdf_url":null
}
],
}
我想确定任何 属性 的值是否具有数组结构。到目前为止我能想到的最好的是:
StreamReader streamrr = new StreamReader("C:\temp\agfarm_example_udate.json", Encoding.UTF8);
string JSON = streamrr.ReadToEnd();
JObject CWFile = JObject.Parse(JSON);
foreach (JProperty property in CWFile.Properties())
{
// Do something
if (property.Value.ToString().Contains("["))
{
// Do something with the array
JArray items = (JArray)CWFile[property.Name];
foreach (JObject o in items.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
// Do something
}
}
}
}
为了判断一个属性值是否有一个数组,我使用了条件:
if (property.Value.ToString().Contains("["))
我只是想知道是否有更好的方法来进行这项检查?
一种方法是检查 JToken.Type
属性。数组的类型为 JTokenType.Array
:
if (property.Value.Type == JTokenType.Array)
{
var items = (JArray)property.Value;
// Proceed as before.
}
或者,您可以尝试转换为 JArray
:
if (property.Value is JArray)
{
var items = (JArray)property.Value;
// Proceed as before.
}
两者都比检查 property.Value.ToString().Contains("[")
更可取,因为嵌套的 属性 可能有一个数组值,从而导致括号出现在 ToString()
return 的某处。
如果想递归查找每个属性有一个数组值,可以引入扩展方法:
public static class JsonExtensions
{
public static IEnumerable<JToken> WalkTokens(this JToken node)
{
if (node == null)
yield break;
yield return node;
foreach (var child in node.Children())
foreach (var childNode in child.WalkTokens())
yield return childNode;
}
}
然后做:
var CWFile = JToken.Parse(JSON)
var arrayProperties = CWFile.WalkTokens().OfType<JProperty>().Where(prop => prop.Value.Type == JTokenType.Array);
public void Traverse(string name, JToken j)
{
foreach (JToken token in j.AsJEnumerable())
if (token.Type == JTokenType.Object)
{
foreach (var pair in token as JObject)
{
string name_ = pair.Key;
JToken child = pair.Value;
Traverse(name, child);
}
}
else if (token.Type == JTokenType.Array) //an array property found
{
foreach (var child in token.Children())
Traverse(((JProperty)j).Name, child);
}
else if (token.Type == JTokenType.Property)
{
var property = token as JProperty; //current level property
Traverse(name, (JContainer)token);
}
else //current level property name & value
{
var nm = "";
var t = "";
if (j is JProperty)
{
nm = ((JProperty)j).Name;
t = Convert.ToString(((JProperty)j).Value);
}
t = Convert.ToString(token);
}
}
致电:
JSON = JObject.Parse(...);
Traverse("", JSON);
出于同样的原因解析和已经解析的文本不是很明智:
if (property.Value.ToString().Contains(""))
Json 结构简单:对象、数组、属性、值
所以数组是 json 的众所周知的对象,我们正在寻找它:
if (token.Type == JTokenType.Array) //一个数组 属性
我有一个 JSON 文件:
{
"abn":"63119059513",
"acn":"119059513",
"business_structure":"Private Company",
"ngr_number":"1231231",
"cbh_number":"1231231",
"main_name":"Brickworks Building Products Pty Ltd",
"trading_name":"Brickworks",
"other_trading_names":"Austral Bricks",
"directors":[
{
"ID":"12114",
"ae_forms_filled_in_ID":"22739",
"name":"John Smith",
"dob":"1983-10-29",
"address_line_1":"123 Fake Street",
"address_line_2":"",
"address_line_city":"Fakeland",
"address_line_postcode":"2000",
"address_line_state":"New South Wales",
"address_line_country":"Australia",
"order_extract_id":null,
"director_found":null,
"drivers_lic":"",
"home_mortgage":"",
"phone":"",
"mobile":"",
"director_email":"",
"director_title":"Mr",
"director_position":"Director",
"dir_pdf_url":null
}
],
}
我想确定任何 属性 的值是否具有数组结构。到目前为止我能想到的最好的是:
StreamReader streamrr = new StreamReader("C:\temp\agfarm_example_udate.json", Encoding.UTF8);
string JSON = streamrr.ReadToEnd();
JObject CWFile = JObject.Parse(JSON);
foreach (JProperty property in CWFile.Properties())
{
// Do something
if (property.Value.ToString().Contains("["))
{
// Do something with the array
JArray items = (JArray)CWFile[property.Name];
foreach (JObject o in items.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
// Do something
}
}
}
}
为了判断一个属性值是否有一个数组,我使用了条件:
if (property.Value.ToString().Contains("["))
我只是想知道是否有更好的方法来进行这项检查?
一种方法是检查 JToken.Type
属性。数组的类型为 JTokenType.Array
:
if (property.Value.Type == JTokenType.Array)
{
var items = (JArray)property.Value;
// Proceed as before.
}
或者,您可以尝试转换为 JArray
:
if (property.Value is JArray)
{
var items = (JArray)property.Value;
// Proceed as before.
}
两者都比检查 property.Value.ToString().Contains("[")
更可取,因为嵌套的 属性 可能有一个数组值,从而导致括号出现在 ToString()
return 的某处。
如果想递归查找每个属性有一个数组值,可以引入扩展方法:
public static class JsonExtensions
{
public static IEnumerable<JToken> WalkTokens(this JToken node)
{
if (node == null)
yield break;
yield return node;
foreach (var child in node.Children())
foreach (var childNode in child.WalkTokens())
yield return childNode;
}
}
然后做:
var CWFile = JToken.Parse(JSON)
var arrayProperties = CWFile.WalkTokens().OfType<JProperty>().Where(prop => prop.Value.Type == JTokenType.Array);
public void Traverse(string name, JToken j)
{
foreach (JToken token in j.AsJEnumerable())
if (token.Type == JTokenType.Object)
{
foreach (var pair in token as JObject)
{
string name_ = pair.Key;
JToken child = pair.Value;
Traverse(name, child);
}
}
else if (token.Type == JTokenType.Array) //an array property found
{
foreach (var child in token.Children())
Traverse(((JProperty)j).Name, child);
}
else if (token.Type == JTokenType.Property)
{
var property = token as JProperty; //current level property
Traverse(name, (JContainer)token);
}
else //current level property name & value
{
var nm = "";
var t = "";
if (j is JProperty)
{
nm = ((JProperty)j).Name;
t = Convert.ToString(((JProperty)j).Value);
}
t = Convert.ToString(token);
}
}
致电:
JSON = JObject.Parse(...);
Traverse("", JSON);
出于同样的原因解析和已经解析的文本不是很明智:
if (property.Value.ToString().Contains(""))
Json 结构简单:对象、数组、属性、值
所以数组是 json 的众所周知的对象,我们正在寻找它:
if (token.Type == JTokenType.Array) //一个数组 属性