繁体   English   中英

属性包含时如何解析 JTOKEN

[英]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

它可以满足您的基本要求。

关于属性名称中带有句点的任何内容,我查看了源代码,它看起来并不支持您所面临的场景。

https://github.com/JamesNK/Newtonsoft.Json/blob/d0a328e8a46304d62d2174b8bba54721d02be3d3/Src/Newtonsoft.Json/Linq/JsonPath/JPath.cs

它创建了一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM