[英]How to parse JTOKEN when property contains a
我正在尝试解析 JObject,它工作正常,除非该属性包含一个。
例如,我有以下来自 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}}
直到运行时我才知道符号。
我正在做以下解析:
var price = JObject.Parse(response).SelectToken($"{aSymbol}.regularMarketLastPrice").ToString()
请注意 aSymbol = "AAC.U"
此代码适用于所有不包含 a 的符号。
根据您的样本 JSON,您可以这样做...
$.*.regularMarketLastPrice
它可以满足您的基本要求。
关于属性名称中带有句点的任何内容,我查看了源代码,它看起来并不支持您所面临的场景。
它创建了一个JPath
object 来进行解析,它的预期非常有限。 它喜欢方括号、大括号、美元符号和句点,它看起来并没有转义它专门处理的任何特殊字符,但很高兴被证明是错误的……
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;
}
只需解析 json 和 select 一个根元素值
var rootItem = JObject.Parse(json).Properties().FirstOrDefault().Value;
double regularMarketLastPrice= (double) rootItem["regularMarketLastPrice"]; //9.95
或者如果你喜欢艰难的方式
string aSymbol = "AAC.U";
rootItem = JObject.Parse(json).Properties()
.Where(o => o.Name==aSymbol).FirstOrDefault().Value;
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.