2016-09-05 4 views
1

Ich möchte einen reaktiven Strom von json kodierten Strings so filtern:Testen für verschachtelte Schlüssel mit Json.NET?

{ "Key1" : {"key2":"value"}, 
    "key3" : "other values" 
} 

ich nach Artikeln filtern möchten, die einen Wert für key2, wie dieses:

IDisposable valueQuery = globalEventStream 
    .Select(e => JObject.Parse(e.EventArgs.Data)) 
    .Where(e => e["key1"]["key2"] != null) 

Aber das gibt mir der Fehler

Cannot access child value on Newtonsoft.Json.Linq.JValue 

die einzige Art, wie ich um diese zu finden zu bekommen, ist folgendes zu tun:

IDisposable deathDisposable = globalEventStream 
    .Select(e => JObject.Parse(e.EventArgs.Data)) 
    .Where(e => e["key1"] != null).Select(e => e["key1"]) 
    .Where(e => e["key2"] != null).Select(e => e["key2"]) 

Gibt es eine Möglichkeit, nach verschachtelten Schlüsseln mit einer einzigen Where-Anweisung zu filtern?

Antwort

3

können Sie JToken.SelectTokens() verwenden, um verschachtelte Abfragen auf LINQ to JSON-Objekte zu laufen:

var valueQuery = globalEventStream 
    .Select(e => JObject.Parse(e.EventArgs.Data)) 
    .Where(o => o.SelectTokens("Key1.key2").Any()); 

Probe fiddle.

Die Spezifikation für JSONPath here und unterstützt die folgende Abfrage Syntax:

XPath JSONPath Description 
/  $   the root object/element 
.  @   the current object/element 
/  . or []  child operator 
..  n/a   parent operator 
//  ..   recursive descent. JSONPath borrows this syntax from E4X. 
*  *   wildcard. All objects/elements regardless their names. 
@  n/a   attribute access. JSON structures don't have attributes. 
[]  []   subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator. 
|  [,]   Union operator in XPath results in a combination of node sets. JSONPath allows alternate names or array indices as a set. 
n/a  [start:end:step] array slice operator borrowed from ES4. 
[]  ?()   applies a filter (script) expression. 
n/a ()   script expression, using the underlying script engine. 
()  n/a   grouping in Xpath 

zB für die folgenden JSON:

{ "Key1" : [{"NoKey2":"value"}, {"key2":"value"}], "key3" : "other values" } 

Sie könnten den Wildcard-Operator * für die Anwesenheit testen eines beliebigen Elements in dem Array mit einer "key2" Eigenschaft wie folgt:

var valueQuery = globalEventStream 
    .Select(e => JObject.Parse(e.EventArgs.Data)) 
    .Where(o => o.SelectTokens("Key1[*].key2").Any()); 

Hier prüft Enumerable.Any(), ob die SelectTokens() Abfrage mehr als null Ergebnisse gefunden hat - d.h., gibt es mindestens einen Eintrag im "Key1" Array mit einer "key2" Eigenschaft. Es ist effizienter als Enumerable.Count(), da es die Auswertung stoppt, sobald ein Element zurückgegeben wird.

+0

Was bewirkt der Zusatz von 'Any()'? – mooglinux

Verwandte Themen