0

最後に実際に報告された四半期を見つけようとしていますが、それに付随する表示値があります。基準は、@clientsDescription または @displayName が EPS にあることです。私の JSON 文字列は次のようになります。

{
    "?xml": {
        "@version": "1.0",
        "@encoding": "UTF-8"
    },
    "DataFeed": {
        "@FeedName": "issuerDetails",
        "SecurityDetails": {
            "Security": {
                "@sequence": "850",
                "TimesSeriesList": [{
                        "@description": "EPS",
                        "@clientsDescription": "EPS",
                        "FinancialValue": [{
                                "@displayRank": "850",
                                "@estimateActual": "Actual",
                                "@period": "Q1",
                                "@periodEnd": "2015-9-30T00:00:00.00",
                                "@displayName": "EPS",
                                "CurrentValue": {
                                    "@displayValue": "$0.19"
                                }
                            }, {
                                "@displayRank": "850",
                                "@estimateActual": "Actual",
                                "@period": "Q2",
                                "@periodEnd": "2015-12-31T00:00:00.00",
                                "@displayName": "EPS",
                                "CurrentValue": {
                                    "@displayValue": "$0.26"
                                }
                            }, {
                                "@displayRank": "850",
                                "@estimateActual": "Actual",
                                "@period": "Q3",
                                "@periodEnd": "2015-3-31T00:00:00.00",
                                "@displayName": "EPS",
                                "CurrentValue": {
                                    "@displayValue": "$0.34"
                                }
                            }, {
                                "@displayRank": "850",
                                "@estimateActual": "Estimate",
                                "@period": "Q4",
                                "@periodEnd": "2015-6-30T00:00:00.00",
                                "@displayName": "EPS",
                                "CurrentValue": {
                                    "@displayValue": "$0.32"
                                }
                            }, {
                                "@displayRank": "850",
                                "@estimateActual": "Estimate",
                                "@period": "Annual",
                                "@periodEnd": "2015-6-30T00:00:00.00",
                                "@displayName": "EPS",
                                "CurrentValue": {
                                    "@displayValue": "$1.11"
                                }
                            }
                        ]
                    }
                ]
            }
        }
    }
}

json クラスは次のようになります。

public static class JsonExtensions
{
    public static IEnumerable<JToken> DescendantsAndSelf(this JToken node)
    {
        if (node == null)
            return Enumerable.Empty<JToken>();
        var container = node as JContainer;
        if (container != null)
            return container.DescendantsAndSelf();
        else
            return new[] { node };
    }

    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;
    }

    public static IEnumerable<JToken> SingleOrMultiple(this JToken source)
    {
        if (source == null)
            return Enumerable.Empty<JToken>();
        IEnumerable<JToken> arr = source as JArray;
        return arr ?? new[] { source };
    }
}   

誰かが元の XML を要求したので、ここに示します。

<DataFeed FeedName="issuerDetails">
<CompanyDetails></CompanyDetails>
<SecurityDetails minDisplayYear="2014" maxDisplayYear="2020">
<Security sequence="900" primaryIndicator="No">
<TimesSeriesList description="EPS" clientsDescription="EPS" id="1" qualifier="--" currencyName="CAD" currencySymbol="C$" fiscalId="1" fiscalCalendar="Fiscal" qualifierId="0">
<FinancialValue displayRank="900" estimateActual="Actual" period="Q1" periodEnd="2015-12-31T00:00:00.00" displayName="EPS">
<CurrentValue displayValue="$0.45">0.4502</CurrentValue>
</FinancialValue>
<FinancialValue displayRank="900" estimateActual="Actual" period="Q2" periodEnd="2015-3-31T00:00:00.00" displayName="EPS">
<CurrentValue displayValue="$0.43">0.43</CurrentValue>
</FinancialValue>
<FinancialValue displayRank="900" estimateActual="Actual" period="Q3" periodEnd="2015-6-30T00:00:00.00" displayName="EPS">
<CurrentValue displayValue="$0.64">0.64</CurrentValue>
</FinancialValue>
<FinancialValue displayRank="900" estimateActual="Estimate" period="Q4" periodEnd="2015-9-30T00:00:00.00" displayName="EPS">
<CurrentValue displayValue="$0.52">0.52</CurrentValue>
</FinancialValue>
<FinancialValue displayRank="900" estimateActual="Estimate" period="Annual" periodEnd="2015-9-30T00:00:00.00" displayName="EPS">
<CurrentValue displayValue="$2.03">2.0325</CurrentValue>
</FinancialValue>
<FinancialValue displayRank="900" estimateActual="Estimate" period="Q1" periodEnd="2016-12-31T00:00:00.00" displayName="EPS">
<CurrentValue displayValue="$0.56">0.56</CurrentValue>
</FinancialValue>
</TimesSeriesList>
</Security>
</SecurityDetails>
</DataFeed>

JSON フィードのコードは次のようになります。

from securityDetail in jsonFeed
    .SelectTokens("DataFeed.SecurityDetails.Security.TimesSeriesList")
    .SelectMany(i => i.ObjectsOrSelf())
let metric = securityDetail
     .SelectToken("@clientDescription")
     .SingleOrMultiple()
     .Select(t => (string)t)
     .ToArray()
where metric.Equals("EPS") && metric != null
let finValues = securityDetail.SelectTokens("FinancialValue")
    .SelectMany(d => d.ObjectsOrSelf())
orderby finValues.SelectToken("@periodEnd") descending  // <-- getting a error here
orderby finValues.SelectToken("@period") descending
select new 
{
    LastRptQtr = string.format("{0}{1}",
            (string)(finValues
                .SelectToken("@periodEnd").FirstOrDefault()).Substring(0, 4),
            (string)finValues
                .SelectToken("@period").FirstOrDefault()),
        DispVal = finValues
            .SelectToken("CurrentValue.@displayValue").FirstOrDefault()
}

最後に、私は必要です:

LastRptQtr = "2015Q3"
DispVal = "$0.34"

次のエラーが表示されます。

'IEnumerable<JObject>' does not contain a definition for 'SelectToken' 
and no extension method 'SelectToken' accepting a first argument of 
type 'IEnumerable<JObject>' could be found

私は何を間違っていますか?

4

3 に答える 3

2

古典的なXY 問題

ハンマーしか持っていない場合、すべてが釘のように見えます。元の xml を json に変換する必要はありません。元の xml での作業がより簡単になります。

Linq2Xml + Xpath の使用

var xDoc = XDocument.Parse(xmlstring);
var elements = xDoc.XPathSelectElements("//*[@periodEnd and (@clientsDescription='EPS' or @displayName='EPS')]")
                .OrderBy(x => (DateTime)x.Attribute("periodEnd"))
                .Select(x=>new {
                    PeriodEnd = (DateTime)x.Attribute("periodEnd"),
                    DispVal = (string)x.Element("CurrentValue").Attribute("displayValue")
                })
                .ToList();
于 2017-01-06T22:47:36.400 に答える