I have a polymorphic json string. Here's what it looks like:
{
"Product" : {
"Context" : {
"IssuerDetails" : {
"Issuer" : {
"@clientCode" : "BMTEST-CA",
"@companyName" : "zTest BM Company, Inc",
"@companyId" : "1",
"IssuerChanges" : [{
"@type" : "Book Value",
"@previous" : "$9.06",
"@current" : "$55.34"
}, {
"@type" : "Price Target",
"@previous" : "$50.00",
"@current" : "$199.00"
}, {
"@type" : "EPS",
"@previous" : "2.10",
"@current" : "2.09",
"@period" : "5",
"@year" : "2017"
}, {
"@type" : "Income Tax",
"@previous" : "56",
"@current" : "55",
"@period" : "5",
"@year" : "2015"
}
],
"SecurityDetails" : {
"Security" : {
"@primaryIndicator" : "Yes",
"Clusters" : [{
"@name" : "Company Data",
"@rank" : "2",
"FinancialValue" : [{
"@financialsType" : "Dividend",
"CurrentValue" : {
"@displayValue" : "$5.02",
}
}, {
"@financialsType" : "Book Value",
"CurrentValue" : {
"@displayValue" : "$55.34",
},
"PreviousValue" : {
"@displayValue" : "$9.06",
"@type" : "INCREASE",
}
}
]
}, {
"@rank" : "1",
"@name" : "AAPL & Market Data",
"FinancialValue" : [{
"@financialsType" : "Rating",
"@shortCode" : "Mkt",
"CurrentValue" : {
"@displayValue" : "Market Perform",
}
}, {
"@financialsType" : "Rating Qualifier",
"CurrentValue" : {
"@displayValue" : "Speculative",
}
}
]
}
]
}
}
}
}
}
}
}
I'm using the following extension class:
public static class JsonExtensions
{
public static IEnumerable<JObject> ObjectsOrSelf(this JToken root)
{
if (root is JObject)
yield return (JObject)root;
else if (root is JContainer)
foreach (var item in ((JContainer)root).Children())
foreach (var child in item.ObjectsOrSelf())
yield return child;
else
yield break;
}
}
Based on that, here's my query:
JObject feed = JObject.Parse(jsonText);
var compInfo = from issuer in feed.SelectTokens("Product.Context.IssuerDetails.Issuer").SelectMany(i => i.ObjectsOrSelf())
let issuerChanges = issuer.SelectTokens("IssuerChanges").SelectMany(s => s.ObjectsOrSelf())
where issuerChanges != null
let finValues = issuer.SelectTokens("SecurityDetails.Security.Clusters").SelectMany(s => s.ObjectsOrSelf())
where finValues != null
select new
{
Id = (int)issuer["@companyId"],
BMOTicker = (string)issuer["@clientCode"],
CompName = (string)issuer["@companyName"],
ChngsType = issuerChanges.Select(c => (string)c["@type"]),
PrevChng = issuerChanges.Select(c => (string)c["@previous"]),
CurrChng = issuerChanges.Select(c => (string)c["@current"]),
Period = issuerChanges.Select(c => (string)c["@period"]),
Year = issuerChanges.Select(c => (string)c["@year"]),
FinValueName = finValues.Select(c => (string)c["@financialsType"])
};
When I tried the query, I don't get an error but get the following (from LinqPad):
The end result should look like this (simulated in Excel):
Any idea how can I get the end result?