SEDOL と ADP 値のリストを取得しようとしています。以下は私のjsonテキストです:
{
"DataFeed" : {
"@FeedName" : "AdminData",
"Issuer" : [{
"id" : "1528",
"name" : "ZYZ.A a Test Company",
"clientCode" : "ZYZ.A",
"securities" : {
"Security" : {
"id" : "1537",
"sedol" : "SEDOL111",
"coverage" : {
"Coverage" : [{
"analyst" : {
"@id" : "164",
"@clientCode" : "SJ",
"@firstName" : "Steve",
"@lastName" : "Jobs",
"@rank" : "1"
}
}, {
"analyst" : {
"@id" : "261",
"@clientCode" : "BG",
"@firstName" : "Bill",
"@lastName" : "Gates",
"@rank" : "2"
}
}
]
},
"customFields" : {
"customField" : [{
"@name" : "ADP Security Code",
"@type" : "Textbox",
"values" : {
"value" : "ADPSC1111"
}
}, {
"@name" : "Top 10 - Select one or many",
"@type" : "Dropdown, multiple choice",
"values" : {
"value" : ["Large Cap", "Cdn Small Cap", "Income"]
}
}
]
}
}
}
}, {
"id" : "1519",
"name" : "ZVV Test",
"clientCode" : "ZVV=US",
"securities" : {
"Security" : [{
"id" : "1522",
"sedol" : "SEDOL112",
"coverage" : {
"Coverage" : {
"analyst" : {
"@id" : "79",
"@clientCode" : "MJ",
"@firstName" : "Michael",
"@lastName" : "Jordan",
"@rank" : "1"
}
}
},
"customFields" : {
"customField" : [{
"@name" : "ADP Security Code",
"@type" : "Textbox",
"values" : {
"value" : "ADPS1133"
}
}, {
"@name" : "Top 10 - Select one or many",
"@type" : "Dropdown, multiple choice",
"values" : {
"value" : ["Large Cap", "Cdn Small Cap", "Income"]
}
}
]
}
}, {
"id" : "1542",
"sedol" : "SEDOL112",
"customFields" : {
"customField" : [{
"@name" : "ADP Security Code",
"@type" : "Textbox",
"values" : {
"value" : "ADPS1133"
}
}, {
"@name" : "Top 10 - Select one or many",
"@type" : "Dropdown, multiple choice",
"values" : {
"value" : ["Large Cap", "Cdn Small Cap", "Income"]
}
}
]
}
}
]
}
}
]
}
}
これが私がこれまでに持っているコードです:
var compInfo = feed["DataFeed"]["Issuer"]
.Select(p => new {
Id = p["id"],
CompName = p["name"],
SEDOL = p["securities"]["Security"].OfType<JArray>() ?
p["securities"]["Security"][0]["sedol"] :
p["securities"]["Security"]["sedol"]
ADP = p["securities"]["Security"].OfType<JArray>() ?
p["securities"]["Security"][0]["customFields"]["customField"][0]["values"]["value"] :
p["securities"]["Security"]["customFields"]["customField"][0]["values"]["value"]
});
私が得るエラーは次のとおりです。
無効なキー値「sedol」で JArray 値にアクセスしました。Int32 配列インデックスが必要です
私はこれを理解することに本当に近づいていると思います。コードを修正するにはどうすればよいですか? SEDOL
とを取得する代替手段がある場合は、ADP value
お知らせください。
[UPDATE1]動的 ExpandoObject の使用を開始しました。これまでに使用したコードは次のとおりです。
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, new ExpandoObjectConverter());
foreach (dynamic element in obj)
{
Console.WriteLine(element.DataFeed.Issuer[0].id);
Console.WriteLine(element.DataFeed.Issuer[0].securities.Security.sedol);
Console.ReadLine();
}
しかし、私は今、エラーが発生しています'ExpandoObject' does not contain a definition for 'DataFeed' and no extension method 'DataFeed' accepting a first argument of type 'ExpandoObject' could be found
。 注:この json テキストの形式が正しくないことは理解しています。1 つのインスタンスには配列があり、もう 1 つはオブジェクトです。両方のインスタンスを処理できるように、コードを機敏にする必要があります。
[UPDATE2]これまで私のコードを手伝ってくれた @dbc に感謝します。現在の環境に厳密に一致するように、上記の json テキストを更新しました。SEDOL と ADP コードを取得できるようになりました。ただし、最初のアナリストを取得しようとすると、コードはオブジェクトに対してのみ機能し、配列の一部であるアナリストに対して null を生成します。これが私の現在のコードです:
var compInfo = from issuer in feed.SelectTokens("DataFeed.Issuer").SelectMany(i => i.ObjectsOrSelf())
let security = issuer.SelectTokens("securities.Security").SelectMany(s => s.ObjectsOrSelf()).FirstOrDefault()
where security != null
select new
{
Id = (string)issuer["id"], // Change to (string)issuer["id"] if id is not necessarily numeric.
CompName = (string)issuer["name"],
SEDOL = (string)security["sedol"],
ADP = security["customFields"]
.DescendantsAndSelf()
.OfType<JObject>()
.Where(o => (string)o["@name"] == "ADP Security Code")
.Select(o => (string)o.SelectToken("values.value"))
.FirstOrDefault(),
Analyst = security["coverage"]
.DescendantsAndSelf()
.OfType<JObject>()
.Select(jo => (string)jo.SelectToken("Coverage.analyst.@lastName"))
.FirstOrDefault(),
};
常に最初のアナリストを選択するには、何を変更する必要がありますか?