Ausgabe
Ich versuche, JObject zu analysieren, was gut funktioniert, es sei denn, die Eigenschaft enthält eine .
Zum Beispiel habe ich die folgende Antwort von der API:
{"AAC.U":{"assetType":"EQUITY","assetMainType":"EQUITY","cusip":"G33032114","assetSubType":"","symbol":"AAC.U","description":"Ares Acquisition Corporation Units, each consisting of one Class A ordinary shar","bidPrice":9.78,"bidSize":1200,"bidId":"P","askPrice":10.0,"askSize":200,"askId":"P","lastPrice":9.95,"lastSize":100,"lastId":"N","openPrice":9.95,"highPrice":9.95,"lowPrice":9.95,"bidTick":" ","closePrice":9.95,"netChange":0.0,"totalVolume":2600,"quoteTimeInLong":1665000010602,"tradeTimeInLong":1665010800002,"mark":9.95,"exchange":"n","exchangeName":"NYSE","marginable":true,"shortable":false,"volatility":0.0,"digits":2,"52WkHigh":10.11,"52WkLow":9.8,"nAV":0.0,"peRatio":0.0,"divAmount":0.0,"divYield":0.0,"divDate":"","securityStatus":"Normal","regularMarketLastPrice":9.95,"regularMarketLastSize":1,"regularMarketNetChange":0.0,"regularMarketTradeTimeInLong":1665010800002,"netPercentChangeInDouble":0.0,"markChangeInDouble":0.0,"markPercentChangeInDouble":0.0,"regularMarketPercentChangeInDouble":0.0,"delayed":false,"realtimeEntitled":true}}
Ich kenne das Symbol bis zur Laufzeit nicht.
Ich mache folgendes zu analysieren:
var price = JObject.Parse(response).SelectToken($"{aSymbol}.regularMarketLastPrice").ToString()
Beachten Sie, dass aSymbol = “AAC.U”
Dieser Code funktioniert gut für alle Symbole, die KEIN enthalten.
Lösung
Basierend auf Ihrem Beispiel-JSON können Sie dies tun …
$.*.regularMarketLastPrice
Es kommt Sie für Ihre Grundanforderung aus.
In Bezug auf alles mit einem Punkt im Eigenschaftsnamen habe ich mir den Quellcode angesehen und es sieht nicht so aus, als würde er das Szenario unterstützen, mit dem Sie konfrontiert sind.
Es erstellt ein JPath
Objekt, das die Analyse durchführt, und es ist ziemlich begrenzt auf das, was es erwartet. Es mag Klammern, Klammern, Dollarzeichen und Punkte, es sieht nicht so aus, als würde es irgendwelchen Sonderzeichen entgehen, mit denen es sich speziell befasst, freut sich aber, wenn es sich als falsch herausstellt …
private void ParseMain()
{
int currentPartStartIndex = _currentIndex;
EatWhitespace();
if (_expression.Length == _currentIndex)
{
return;
}
if (_expression[_currentIndex] == '$')
{
if (_expression.Length == 1)
{
return;
}
// only increment position for "$." or "$["
// otherwise assume property that starts with $
char c = _expression[_currentIndex + 1];
if (c == '.' || c == '[')
{
_currentIndex++;
currentPartStartIndex = _currentIndex;
}
}
if (!ParsePath(Filters, currentPartStartIndex, false))
{
int lastCharacterIndex = _currentIndex;
EatWhitespace();
if (_currentIndex < _expression.Length)
{
throw new JsonException("Unexpected character while parsing path: " + _expression[lastCharacterIndex]);
}
}
}
private bool ParsePath(List<PathFilter> filters, int currentPartStartIndex, bool query)
{
bool scan = false;
bool followingIndexer = false;
bool followingDot = false;
bool ended = false;
while (_currentIndex < _expression.Length && !ended)
{
char currentChar = _expression[_currentIndex];
switch (currentChar)
{
case '[':
case '(':
if (_currentIndex > currentPartStartIndex)
{
string? member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
if (member == "*")
{
member = null;
}
filters.Add(CreatePathFilter(member, scan));
scan = false;
}
filters.Add(ParseIndexer(currentChar, scan));
scan = false;
_currentIndex++;
currentPartStartIndex = _currentIndex;
followingIndexer = true;
followingDot = false;
break;
case ']':
case ')':
ended = true;
break;
case ' ':
if (_currentIndex < _expression.Length)
{
ended = true;
}
break;
case '.':
if (_currentIndex > currentPartStartIndex)
{
string? member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
if (member == "*")
{
member = null;
}
filters.Add(CreatePathFilter(member, scan));
scan = false;
}
if (_currentIndex + 1 < _expression.Length && _expression[_currentIndex + 1] == '.')
{
scan = true;
_currentIndex++;
}
_currentIndex++;
currentPartStartIndex = _currentIndex;
followingIndexer = false;
followingDot = true;
break;
default:
if (query && (currentChar == '=' || currentChar == '<' || currentChar == '!' || currentChar == '>' || currentChar == '|' || currentChar == '&'))
{
ended = true;
}
else
{
if (followingIndexer)
{
throw new JsonException("Unexpected character following indexer: " + currentChar);
}
_currentIndex++;
}
break;
}
}
bool atPathEnd = (_currentIndex == _expression.Length);
if (_currentIndex > currentPartStartIndex)
{
string? member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex).TrimEnd();
if (member == "*")
{
member = null;
}
filters.Add(CreatePathFilter(member, scan));
}
else
{
// no field name following dot in path and at end of base path/query
if (followingDot && (atPathEnd || query))
{
throw new JsonException("Unexpected end while parsing path.");
}
}
return atPathEnd;
}
Beantwortet von – Skin
Antwort geprüft von – Dawn Plyler (FixError Volunteer)