Is there a way to get list of specific element in JSON using C# and Newtonsoft

huangapple go评论64阅读模式
英文:

Is there a way to get list of specific element in JSON using C# and Newtonsoft

问题

Sure, here's the translated code portion:

我只想循环遍历 "RiskId"  "Occupants" 的列表并显示值。

如果我这样做....
```csharp
var jsonObj = (JObject)JsonConvert.DeserializeObject(jsonstring);

var jsonResult = jsonObj.SelectToken("Risks.RiskId").Select(m => m.Value<string>());

我得到以下错误

System.ArgumentNullException: '无法为 null 的值。参数名称: source'


<details>
<summary>英文:</summary>

Im trying to get a list of all the  &quot;Occupants&quot; and &quot;RiskId&quot; from the JSON below using C# and Newtonsoft. 

 

Not sure what I&#39;m doing wrong here. Thanks for your help.

{
"Header": {
"MatchType": "Exact",
"TotalResultCount": 2,
"PreviousPageUrl": null,
"NextPageUrl": null,
"AvailableProductsForRequestedAddress": "https://prometrixapiuat.iso.com/uw/address/productList?City=MONTEBELLO&State=CA&StreetName=423+W+OLYMPIC+BLVD&Zip=90640"
},
"Risks": [
{
"RiskId": "64CX99016399",
"BuildingDescription": "MONTEBELLO PLASTICS INC (1S)",
"SurveyDates": {
"ScheduleAppliedDate": "04/21/1999",
"LatestPhoneSurveyDate": "",
"OnsiteSurveyDate": "05/01/1999"
},
"Location": {
"Latitude": null,
"Longitude": null,
"Address": {
"StreetAddress1": "423 W OLYMPIC BLVD",
"City": "MONTEBELLO",
"PostalCity": "MONTEBELLO",
"State": "CA",
"Zip": "90640",
"Zip4": "5225",
"County": "LOS ANGELES"
},
"AlternateAddresses": []
},
"Occupants": [
{
"Name": "MFG STORAGE - PACKAGING MATERIALS",
"OccupantId": "15"
}
],
"ProductListUrl": "https://prometrixapiuat.iso.com/uw/Risk/64CX99016399/ProductList",
"YearBuilt": 1960,
"FireProtectionArea": "MONTEBELLO"
},
{
"RiskId": "64CX99016400",
"BuildingDescription": "MONTEBELLO PLASTICS INC (1S)",
"SurveyDates": {
"ScheduleAppliedDate": "04/21/1999",
"LatestPhoneSurveyDate": "",
"OnsiteSurveyDate": "05/01/1999"
},
"Location": {
"Latitude": null,
"Longitude": null,
"Address": {
"StreetAddress1": "423 W OLYMPIC BLVD",
"City": "MONTEBELLO",
"PostalCity": "MONTEBELLO",
"State": "CA",
"Zip": "90640",
"Zip4": "5225",
"County": "LOS ANGELES"
},
"AlternateAddresses": []
},
"Occupants": [
{
"Name": "MFG STORAGE - PACKAGING MATERIALS",
"OccupantId": "15"
}
],
"ProductListUrl": "https://prometrixapiuat.iso.com/uw/Risk/64CX99016400/ProductList",
"YearBuilt": 1960,
"FireProtectionArea": "MONTEBELLO"
}
]
}



I would just like to loop through the list of  &quot;RiskId&quot; and &quot;Occupants&quot; and display the value.


If I do ....

var jsonObj = (JObject)JsonConvert.DeserializeObject(jsonstring);

var jsonResult = jsonObj.SelectToken("Risks.RiskId").Select(m => m.Value<string>());


I&#39;m getting below error 
 
System.ArgumentNullException: &#39;Value cannot be null.
Parameter name: source&#39;

</details>


# 答案1
**得分**: 1

变量jsonResult将包含所有Risks数组中的RiskId属性,使用SelectTokens()函数获取。
请注意:

  1. "RiskId"属性嵌套在对象数组Risks[*].RiskId中,因此路径必须包含数组索引器,如[*][0][*]选择所有RiskId属性。
  2. 由于"RiskId"属性位于数组中且不止一个,使用SelectTokens()而不是SelectToken()来获取它们。
  3. 如果不确定要选择属性的路径,可以使用递归下降运算符..选择所有具有该名称的属性,然后使用JToken.Path获取每个属性的实际路径。
    对于您的JSON,

    var paths = jsonObj.SelectTokens("..RiskId").Select(m => m.Path).ToList();
    

    返回

    [
      "Risks[0].RiskId",
      "Risks[1].RiskId"
    ]
    

    从中您可以看到,在原始查询中应该使用的正确路径是"Risks[*].RiskId"
    演示链接:https://dotnetfiddle.net/Lwrvdv


<details>
<summary>英文:</summary>

You may do:

	var jsonResult = jsonObj.SelectTokens(&quot;Risks[*].RiskId&quot;)
		.Select(m =&gt; m.Value&lt;string&gt;())
		.ToList();

Notes:

 1. The `&quot;RiskId&quot;` properties are nested in an array of objects `Risks[*].RiskId`, thus an array indexer such as `[*]` or `[0]` must be included in the path.  `[*]` selects **all** `RiskId` properties.

 2. Since the `&quot;RiskId&quot;` properties are in an array and there is more than one, use [`SelectTokens()`](https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JToken_SelectTokens.htm) rather than `SelectToken()` to get them all.

 3. If you are unsure of the path to use to select a property by name, you may use the **recursive descent** operator `..` to select all properties with that name, and then use [`JToken.Path`](https://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Linq_JToken_Path.htm) to get the actual path of each.  

    Thus, for your JSON, 

    ```
    var paths = jsonObj.SelectTokens(&quot;...RiskId&quot;).Select(m =&gt; m.Path).ToList();
    ```
    
    Returns

    ```json
    [
      &quot;Risks[0].RiskId&quot;,
      &quot;Risks[1].RiskId&quot;
    ]
    ```
 
    From which you can see that the correct path to use in the original query should have been `&quot;Risks[*].RiskId&quot;`.

Demo here: https://dotnetfiddle.net/Lwrvdv


</details>



# 答案2
**得分**: 1

以下是代码的中文翻译:

```csharp
昨天我向你展示了这种类型的代码
JArray risks = (JArray) JObject.Parse(jsonstring)["Risks"];

var riskId = risks.Select(r => (string) r["RiskId"]).FirstOrDefault(); // "64CX99016400"

JArray occupants = risks.Select(r => (JArray) r["Occupants"]).FirstOrDefault());
更新

 @dbc 更新后,如果你有多个风险项,只需移除FirstOrDefault()
string[] riskIds = risks.Select(r => (string) r["RiskId"]);

Response.Write(string.Join(", ", riskIds)); // "64CX99016399, 64CX99016400"

List<JArray> occupants = risks.Select(r => (JArray) r["Occupants"]).ToList();

int[] occupantIds = occupants.SelectMany(o => 
                                o.Select(o => (int) o["OccupantId"])).ToArray();

Response.Write(string.Join(", ", occupantIds)); // "15, 15";
英文:

I showed you this kind of code yesterday

JArray risks = (JArray) JObject.Parse(jsonstring)[&quot;Risks&quot;];

var riskId = risks.Select(r =&gt; (string) r[&quot;RiskId&quot;] ).FirstOrDefault(); // &quot;64CX99016400&quot;
	
JArray occupants = risks.Select(r =&gt; (JArray) r[&quot;Occupants&quot;] ).FirstOrDefault());

UPDATE

after @dbc update, if you can have several risks items, just remove firstordefault()

string[] riskIds = risks.Select(r =&gt; (string) r[&quot;RiskId&quot;] );

Response.Write(string.Join(&quot;, &quot;,riskIds)); // &quot;64CX99016399, 64CX99016400&quot;

List&lt;JArray&gt; occupants = risks.Select(r =&gt; (JArray) r[&quot;Occupants&quot;] ).ToList();

int[] occupantIds = occupants.SelectMany(o =&gt; 
	                            o.Select(o =&gt; (int)o[&quot;OccupantId&quot;])).ToArray();

Response.Write(string.Join(&quot;, &quot;,occupantIds)); // &quot;15, 15&quot;;

huangapple
  • 本文由 发表于 2023年5月13日 23:12:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76243440.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定