识别 属性 的值是一个数组

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 结构简单:对象、数组、属性、值

http://www.json.org/

所以数组是 json 的众所周知的对象,我们正在寻找它:

if (token.Type == JTokenType.Array) //一个数组 属性