web-dev-qa-db-ja.com

C#のJson.NETでJSON文字列の要素数をカウントする

次のようなJSON文字列があります。

{
"package1": {
    "type": "envelope",
    "quantity": 1,
    "length": 6,
    "width": 1,
    "height": 4
},
"package2": {
    "type": "box",
    "quantity": 2,
    "length": 9,
    "width": 9,
    "height": 9
}
}

Json.NET LINQ to JSON機能を使用してJSON文字列を処理していますが、ノード/要素/キーの総数をどのように見つけることができるのか疑問に思っています(それらを何と呼ぶか​​はよくわかりません)。ストリング。たとえば、上記の文字列にはpackage1とpackage2があるので、整数2を返すようにするにはどうすればよいのでしょうか。パッケージが1つしかない場合もあります。その場合は、整数1を返します。その他20個のパッケージがある場合があります(その場合は20個を返します)。

私のJObjectは次のようになります。

JObject o = JObject.Parse(myJsonString);

何か案は?助けてくれてありがとう。

11
Brent Barbata
JObject jObj = (JObject)JsonConvert.DeserializeObject(myJsonString);
int count = jObj.Count;

ボーナス:

dynamic jObj = JsonConvert.DeserializeObject(myJsonString);

foreach (var package in jObj)
{
    Console.WriteLine("{0} {1}", package.First.type, package.First.quantity);
}
20
L.B

Cinchoo ETL -オープンソースライブラリを使用すると、ストリーミングアプローチを使用して入力を解析するため、少ないメモリオーバーヘッドでノードカウントを簡単に行うことができます。したがって、大きなファイルも処理できます。

string json = @"{
""package1"": {
""type"": ""envelope"",
""quantity"": 1,
""length"": 6,
""width"": 1,
""height"": 4
},
""package2"": {
""type"": ""box"",
""quantity"": 2,
""length"": 9,
""width"": 9,
""height"": 9
}
}";

using (var p = ChoJSONReader.LoadText(json).WithJSONPath("$.*"))
{
    Console.WriteLine(p.Count());
}

それが役に立てば幸い。

0
RajN

再帰バージョン(プリミティブ値を持つすべてのプロパティをカウントします)

JObject値の再帰的なカウントをグーグルで検索しようとしてこの質問に出くわしましたが、他の多くの質問は見つかりませんでした。そのため、私が思いついたものをこの質問にも追加すると考えました。

_int CountJTokenProperties(JToken token)
{
    var sum = 0;

    if (token.Type == JTokenType.Object)
    {
        foreach (var child in token.Value<JObject>())
        {
            sum += CountJTokenProperties(child.Value);
        }
    }
    else if (token.Type == JTokenType.Array)
    {
        foreach (var child in token.Value<JArray>())
        {
            sum += CountJTokenProperties(child);
        }
    }
    else
    {
        sum += 1;
    }

    return sum;
}
_

.Value<JObject>().Value<JArray>()のより良い代替手段があるかもしれませんが、これは機能しているようです。

具体的には、可変サンプルデータを含むnunitテストでこれが必要であり、正しく逆シリアル化されていることを確認したいと思いました。確認する簡単な方法は、C#オブジェクトにデフォルト以外の値がいくつあるかであると判断し、JsonConvertには次の機能があります。

_public int CountNonDefaultProperties(object obj)
{
    // Let JsonConvert do the work of stripping out default values
    var serialized = JsonConvert.SerializeObject(obj, new JsonSerializerSettings
    {
        DefaultValueHandling = DefaultValueHandling.Ignore
    });

    // Recurse into the json structure, which is much simpler than C# Object structure
    var jObj = JObject.Parse(serialized);

    return CountJTokenProperties(jObj);
}
_

_DefaultValueHandling.Ignore_は配列の一部であるデフォルト値を保持するため、その機能が必要な場合は、配列項目を別の方法などでカウントする必要があることに注意してください。このアクティビティは読者に任されています。

https://dotnetfiddle.net/XIZCvh

0
Thymine
 string json= "{
"package1": {
"type": "envelope",
"quantity": 1,
"length": 6,
"width": 1,
"height": 4
 },
 "package2": {
 "type": "box",
 "quantity": 2,
 "length": 9,
 "width": 9,
 "height": 9
 }
 }"; 

 dynamic stuff;
 int count;
 stuff = JsonConvert.DeserializeObject(json);
 foreach(JProperty s in stuff){

  count++;
  }

  Console.WriteLine(count.ToString());

Countプロパティがうまくいかない場合は、代わりにこれを試してください。動的キーワードがその時点で追加されたため、C#バージョンが4.0以降であることを確認してください。

0
DerpyCoder