阅读卡住 JSON 儿童使用 Newtonsoft.json
Getting stuck reading JSON Children using Newtonsoft.json
我在读取根元素的子元素和理解我在下面的 JSON 中出错的地方时遇到问题:
{
"001": {
"peers": [
{
"id": 0,
"server": "1.1.1.1:80",
"name": "1.1.1.1:80",
"backup": false,
"weight": 1,
"state": "up",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 0,
"fails": 0,
"unhealthy": 0
},
"downtime": 0
},
{
"id": 1,
"server": "127.0.0.1:8888",
"name": "127.0.0.1:8888",
"backup": false,
"weight": 1,
"state": "down",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 0,
"fails": 0,
"unhealthy": 0
},
"downtime": 0
}
],
"keepalive": 0,
"zombies": 0,
"zone": "001"
},
"002": {
"peers": [
{
"id": 0,
"server": "1.1.1.2:80",
"name": "1.1.1.2:80",
"backup": false,
"weight": 1,
"state": "up",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 0,
"fails": 0,
"unhealthy": 0
},
"downtime": 0
},
{
"id": 1,
"server": "127.0.0.1:8888",
"name": "127.0.0.1:8888",
"backup": false,
"weight": 1,
"state": "down",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 0,
"fails": 0,
"unhealthy": 0
},
"downtime": 0
}
],
"keepalive": 0,
"zombies": 0,
"zone": "002"
}
}
我知道我可以将 JSON 传递到 JObject 并通过命名 001
JSON 对象找到下面的服务器值:
JObject obj = JObject.Parse(jsonResponse);
var h = obj.Value<JObject>("001").Value<JArray>("peers")[0].SelectToken("server").ToString();
但是我想读取根元素的子元素(我认为是对象 001
和 002
),不管它们的名称如何,通过它们查找键的值“区域”和“保持活动”。我以为我可以做到这一点:
List<JToken> toks = obj.Root.Children().ToList<JToken>();
string output = "";
foreach (JToken token in toks)
{
JProperty prop = (JProperty)token;
output += prop.Value<string>("zone"); // returns nothing
string bla = token.ToString(); //returns 001 and all it's child objects
}
但输出字符串为空。我可以看到,如果我尝试 token.ToString()
,JToken
对象中有内容,但我似乎无法读取它。
如果我使用 Visual studio 创建一个反序列化对象,我会得到这个根对象,这让我更加困惑:
public class Rootobject
{
public 001 001 { get; set; }
public 002 002 { get; set; }
}
我做错了什么?任何帮助将不胜感激。
乔恩
如果您尝试使用 JTokens
解析此 JSON,您需要了解不同种类的可能标记以及它们之间的关系。您可能会从阅读 .
中受益
在根目录你有一个对象;这个对象有两个属性,叫做“001”和“002”。这些属性各自的值又是对象,包含它们自己的属性(“peers”、“keepalive”、“zombies”和“zone”)。等等。
如果您最终想在不知道其名称的情况下遍历根属性,然后转储子对象的“zone”和“keepalive”属性的值,您可以这样做:
var obj = JObject.Parse(json);
foreach (JProperty prop in obj.Properties())
{
var item = (JObject)prop.Value;
var zone = (string)item["zone"];
var keepalive = (int)item["keepalive"];
Console.WriteLine($"Zone: {zone} keepalive: {keepalive}");
}
Fiddle: https://dotnetfiddle.net/tNut9v
如果 JTokens 让您头晕目眩,那么您最好为 JSON 声明 classes。唯一的问题是根中的动态 属性 名称(“001”、“002”)。但是您可以通过反序列化为 Dictionary<string, T>
来处理该问题,其中 T
是 Item
class,如下所示。像这样定义 classes:
public class Item
{
public List<Peer> peers { get; set; }
public int keepalive { get; set; }
public int zombies { get; set; }
public string zone { get; set; }
}
public class Peer
{
public int id { get; set; }
public string server { get; set; }
public string name { get; set; }
public bool backup { get; set; }
public int weight { get; set; }
public string state { get; set; }
public int active { get; set; }
public int requests { get; set; }
public Responses responses { get; set; }
public int sent { get; set; }
public int received { get; set; }
public int fails { get; set; }
public int unavail { get; set; }
public HealthChecks health_checks { get; set; }
public int downtime { get; set; }
}
public class Responses
{
[JsonProperty("1xx")]
public int code_1xx { get; set; }
[JsonProperty("2xx")]
public int code_2xx { get; set; }
[JsonProperty("3xx")]
public int code_3xx { get; set; }
[JsonProperty("4xx")]
public int code_4xx { get; set; }
[JsonProperty("5xx")]
public int code_5xx { get; set; }
public int total { get; set; }
}
public class HealthChecks
{
public int checks { get; set; }
public int fails { get; set; }
public int unhealthy { get; set; }
}
然后你可以像这样反序列化并转储出你想要的数据:
var dict = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json);
foreach (var kvp in dict)
{
Item item = kvp.Value;
Console.WriteLine($"Zone: {item.zone} keepalive: {item.keepalive}");
}
Fiddle: https://dotnetfiddle.net/3rRmxJ
我在读取根元素的子元素和理解我在下面的 JSON 中出错的地方时遇到问题:
{
"001": {
"peers": [
{
"id": 0,
"server": "1.1.1.1:80",
"name": "1.1.1.1:80",
"backup": false,
"weight": 1,
"state": "up",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 0,
"fails": 0,
"unhealthy": 0
},
"downtime": 0
},
{
"id": 1,
"server": "127.0.0.1:8888",
"name": "127.0.0.1:8888",
"backup": false,
"weight": 1,
"state": "down",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 0,
"fails": 0,
"unhealthy": 0
},
"downtime": 0
}
],
"keepalive": 0,
"zombies": 0,
"zone": "001"
},
"002": {
"peers": [
{
"id": 0,
"server": "1.1.1.2:80",
"name": "1.1.1.2:80",
"backup": false,
"weight": 1,
"state": "up",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 0,
"fails": 0,
"unhealthy": 0
},
"downtime": 0
},
{
"id": 1,
"server": "127.0.0.1:8888",
"name": "127.0.0.1:8888",
"backup": false,
"weight": 1,
"state": "down",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 0,
"fails": 0,
"unhealthy": 0
},
"downtime": 0
}
],
"keepalive": 0,
"zombies": 0,
"zone": "002"
}
}
我知道我可以将 JSON 传递到 JObject 并通过命名 001
JSON 对象找到下面的服务器值:
JObject obj = JObject.Parse(jsonResponse);
var h = obj.Value<JObject>("001").Value<JArray>("peers")[0].SelectToken("server").ToString();
但是我想读取根元素的子元素(我认为是对象 001
和 002
),不管它们的名称如何,通过它们查找键的值“区域”和“保持活动”。我以为我可以做到这一点:
List<JToken> toks = obj.Root.Children().ToList<JToken>();
string output = "";
foreach (JToken token in toks)
{
JProperty prop = (JProperty)token;
output += prop.Value<string>("zone"); // returns nothing
string bla = token.ToString(); //returns 001 and all it's child objects
}
但输出字符串为空。我可以看到,如果我尝试 token.ToString()
,JToken
对象中有内容,但我似乎无法读取它。
如果我使用 Visual studio 创建一个反序列化对象,我会得到这个根对象,这让我更加困惑:
public class Rootobject
{
public 001 001 { get; set; }
public 002 002 { get; set; }
}
我做错了什么?任何帮助将不胜感激。
乔恩
如果您尝试使用 JTokens
解析此 JSON,您需要了解不同种类的可能标记以及它们之间的关系。您可能会从阅读
在根目录你有一个对象;这个对象有两个属性,叫做“001”和“002”。这些属性各自的值又是对象,包含它们自己的属性(“peers”、“keepalive”、“zombies”和“zone”)。等等。
如果您最终想在不知道其名称的情况下遍历根属性,然后转储子对象的“zone”和“keepalive”属性的值,您可以这样做:
var obj = JObject.Parse(json);
foreach (JProperty prop in obj.Properties())
{
var item = (JObject)prop.Value;
var zone = (string)item["zone"];
var keepalive = (int)item["keepalive"];
Console.WriteLine($"Zone: {zone} keepalive: {keepalive}");
}
Fiddle: https://dotnetfiddle.net/tNut9v
如果 JTokens 让您头晕目眩,那么您最好为 JSON 声明 classes。唯一的问题是根中的动态 属性 名称(“001”、“002”)。但是您可以通过反序列化为 Dictionary<string, T>
来处理该问题,其中 T
是 Item
class,如下所示。像这样定义 classes:
public class Item
{
public List<Peer> peers { get; set; }
public int keepalive { get; set; }
public int zombies { get; set; }
public string zone { get; set; }
}
public class Peer
{
public int id { get; set; }
public string server { get; set; }
public string name { get; set; }
public bool backup { get; set; }
public int weight { get; set; }
public string state { get; set; }
public int active { get; set; }
public int requests { get; set; }
public Responses responses { get; set; }
public int sent { get; set; }
public int received { get; set; }
public int fails { get; set; }
public int unavail { get; set; }
public HealthChecks health_checks { get; set; }
public int downtime { get; set; }
}
public class Responses
{
[JsonProperty("1xx")]
public int code_1xx { get; set; }
[JsonProperty("2xx")]
public int code_2xx { get; set; }
[JsonProperty("3xx")]
public int code_3xx { get; set; }
[JsonProperty("4xx")]
public int code_4xx { get; set; }
[JsonProperty("5xx")]
public int code_5xx { get; set; }
public int total { get; set; }
}
public class HealthChecks
{
public int checks { get; set; }
public int fails { get; set; }
public int unhealthy { get; set; }
}
然后你可以像这样反序列化并转储出你想要的数据:
var dict = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json);
foreach (var kvp in dict)
{
Item item = kvp.Value;
Console.WriteLine($"Zone: {item.zone} keepalive: {item.keepalive}");
}
Fiddle: https://dotnetfiddle.net/3rRmxJ