2017-01-06 3 views
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クラスは次のようになります。誰かが元のXMLを求めたので

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

、ここにある:

<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("[email protected]").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 

+1

を使用していますか? –

+0

メソッドObjectsOrSelfは何をしますか? –

+0

私のために働くためにコードを修正するにはどうすればよいですか? –

答えて

2

クラシックXY problem

あなたが持っているすべてをハンマーであれば、すべてが釘のように見えます。オリジナルのXMLをjsonに変換する必要はありません。元のXMLで作業する方が簡単です。

元の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(); 
+0

ありがとうございます。オリジナルのXMLを使って作業する方がより迅速になるようです。 –

0

あなたはJson.Netでこれをかなり簡単に行うことができると思います。

以下のjson文字列を指定します。

var 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"" 
           } 
          } 
         ] 
        } 
       ] 
      } 
     } 
    } 
}"; 

次はあなたがやりたいように見えます:

var obj = JObject.Parse(json); 
obj["DataFeed"]["SecurityDetails"]["Security"]["TimesSeriesList"] 
.Where(x => 
    x.HasValues 
    && x["@clientsDescription"].Value<string>() == "EPS") 
.SelectMany(x => x["FinancialValue"].Children()) 
.Where(x => x["@estimateActual"].Value<string>() == "Actual") 
.Select(x => new { 
    PeriodEnd = x["@periodEnd"].Value<DateTime>(), 
    Period = x["@period"].Value<string>(), 
    DisplayValue = x["CurrentValue"]["@displayValue"].Value<string>(), 
    LastReportQuarter = x["@periodEnd"].Value<DateTime>().Year.ToString() + x["@period"].Value<string>()}) 
.OrderByDescending(x => x.PeriodEnd.Year) 
.ThenByDescending(x => x.Period) 
.First() 
.Dump(); 

PeriodEnd 3/31/2015 12:00:00 AM
Period Q3
DisplayValue $0.34
LastReportQuarter 2015Q3

0

IEnumerableを返すObjectsOrSelf方法、 then節にlet a = data.SelectMany(t=>t.ObjectsOrSelf())変数aはIEnumerableをを入力しており、それがによって拡張する必要がありますfrom b in a

var result = from securityDetail in obj.SelectTokens("DataFeed.SecurityDetails.Security.TimesSeriesList").SelectMany(t => t.ObjectsOrSelf()) 
    let metric = securityDetail.SelectToken("@clientsDescription") 
    where metric != null && metric.Value<String>() == "EPS" 
    let finValues = securityDetail.SelectTokens("FinancialValue").SelectMany(d => d.ObjectsOrSelf()) 
    from v in finValues 
    orderby v.SelectToken("@periodEnd") descending 
    orderby v.SelectToken("@period") descending 
    select new 
    { 
     LastRptQtr = string.Format("{0}{1}", 
      ((string) v.SelectToken("@periodEnd")).Substring(0, 4), 
      (string) v.SelectToken("@period")), 
     DispVal = v.SelectToken("[email protected]").Value<String>() 
    }; 
関連する問題