Как проверить, является ли массив JSON массивом объектов или примитивов? - PullRequest
0 голосов
/ 06 декабря 2018

Название именно то, что я имел в виду

Все вопросы о Stackoverflow спрашивают, является ли данные JSON объектом или массивом, но я ищу, чтобы увидеть, еслиЯ могу выяснить, является ли массив массивом примитивных типов или объектов.

В настоящее время я уже могу определить, является ли он массивом или нет, просто я не могу преобразовать его, если он не является массивомstrings.

Этот код заключен в цикл for, где он находится (var comArrEl в comArr), где comArr - это массив строк.В этом массиве хранится что-то вроде "gesmes: Envelope: Cube: Cube: @ currency =" USD "

В основном мы пытаемся написать здесь универсальную оболочку API.

// Identify if its an array or an object
if (token is JArray)
{
    try
    {
        // Parse the comArrEl to an integer for index access
        if (int.TryParse(comArrEl, out int index))
        {
            // Pump in the array
            var dataList = token.ToObject<List<object>>();

            // Is it the last?
            if (comArrEl != last)
            {
                // let's work it out
                // update the token
                if (index >= 0 && index < dataList.Count)
                {
                    token = JToken.Parse(JsonConvert.SerializeObject(dataList[index]));
                }
            }
            // Yes its the last
            else
            {
                var property = dataList[index];

                // Number checks
                // Make sure the datalist element we're targetting contains a proper value.
                if (decimal.TryParse(property, out decimal val))
                {
                    // Update it
                    _currencyPairComponentService.UpdatePairValue(component.Id, val);
                }
            }
        }
        // Incorrect comArrEl.
        else
        {
            return false;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

Как вывидно, исключение срабатывает в строке 2.

Пример полезной нагрузки для кода:

[
    {
        "@currency": "USD",
        "@rate": "1.1354"
    },
    {
        "@currency": "JPY",
        "@rate": "128.31"
    },
    {
        "@currency": "BGN",
        "@rate": "1.9558"
    },
    {
        "@currency": "CZK",
        "@rate": "25.886"
    },
    {
        "@currency": "DKK",
        "@rate": "7.4630"
    },
    {
        "@currency": "GBP",
        "@rate": "0.88885"
    },
    {
        "@currency": "HUF",
        "@rate": "323.49"
    },
    {
        "@currency": "PLN",
        "@rate": "4.2826"
    },
    {
        "@currency": "RON",
        "@rate": "4.6528"
    },
    {
        "@currency": "SEK",
        "@rate": "10.1753"
    },
    {
        "@currency": "CHF",
        "@rate": "1.1328"
    },
    {
        "@currency": "ISK",
        "@rate": "139.40"
    },
    {
        "@currency": "NOK",
        "@rate": "9.6480"
    },
    {
        "@currency": "HRK",
        "@rate": "7.3990"
    },
    {
        "@currency": "RUB",
        "@rate": "75.8385"
    },
    {
        "@currency": "TRY",
        "@rate": "6.0453"
    },
    {
        "@currency": "AUD",
        "@rate": "1.5569"
    },
    {
        "@currency": "BRL",
        "@rate": "4.3692"
    },
    {
        "@currency": "CAD",
        "@rate": "1.5076"
    },
    {
        "@currency": "CNY",
        "@rate": "7.7848"
    },
    {
        "@currency": "HKD",
        "@rate": "8.8695"
    },
    {
        "@currency": "IDR",
        "@rate": "16344.08"
    },
    {
        "@currency": "ILS",
        "@rate": "4.2293"
    },
    {
        "@currency": "INR",
        "@rate": "80.0660"
    },
    {
        "@currency": "KRW",
        "@rate": "1264.39"
    },
    {
        "@currency": "MXN",
        "@rate": "23.2282"
    },
    {
        "@currency": "MYR",
        "@rate": "4.7165"
    },
    {
        "@currency": "NZD",
        "@rate": "1.6398"
    },
    {
        "@currency": "PHP",
        "@rate": "59.878"
    },
    {
        "@currency": "SGD",
        "@rate": "1.5520"
    },
    {
        "@currency": "THB",
        "@rate": "37.190"
    },
    {
        "@currency": "ZAR",
        "@rate": "15.6366"
    }
]

1 Ответ

0 голосов
/ 06 декабря 2018

Этот метод может динамически повторять JSON-результат, будь то объект или примитив.Этот метод проходит через массив с именем requestComponents , который определяет свойства, которые мы хотим получить из полезной нагрузки JSON.

Затем он разбивает каждую строку requestComponent на массив(то есть "gesmes: Envelope / Cube / Cube / Cube / 0 => @ rate"), чтобы позволить нам спуститься вниз по объекту / массиву.Иногда это массив, иногда объект, мы можем легко пойти по этому пути.Пользовательский синтаксис "=>", который работает только для последнего элемента массива requestComponent, сообщит коду получить это свойство.(sample: 0 => @ currency // Это скажет нам получить объект индекса 0, свойство "@currency")

Вот код, не фокусирующийся на входах, а скорее логика,Главное здесь - заглянуть в готовящееся свойство, чтобы увидеть, является ли он массивом и т. Д. Перед его обработкой.Таким образом, ваша цель может быть

object/array/object/array/array element index

или также может быть

array/object/array/object/property

вуаля

ResponseType является Enum, RequestComponents является объектом, который содержит строку для перемещения(Это все, что имеет значение в этом объекте tbh), а токен - это в основном полезная нагрузка json.

public bool Update(JToken token, ResponseType resType, IEnumerable<RequestComponent> requestComponents)
{
    // For each component we're checking
    foreach (var component in requestComponents)
    {
        var comArr = component.QueryComponent.Split("/"); // Split the string if its nesting
        var last = comArr.LastOrDefault(); // get the last to identify if its the last

        // Iterate the queryComponent Array
        foreach (var comArrEl in comArr)
        {
            // Null check
            if (comArrEl != null)
            {
                // CHECK CURRENT TYPE
                // Identify if its an array or an object
                if (token is JArray)
                {
                    try
                    {
                        // Is it the last?
                        if (comArrEl != last)
                        {
                            // Parse the comArrEl to an integer for index access
                            if (int.TryParse(comArrEl, out int index))
                            {
                                // Pump in the array, treat it as anonymous.
                                var dataList = token.ToObject<List<JObject>>();

                                // let's work it out
                                // update the token
                                if (index >= 0 && index < dataList.Count)
                                {
                                    // Traverse the array
                                    token = JToken.Parse(JsonConvert.SerializeObject(dataList[index]));
                                }
                            }
                        }
                        // Yes its the last
                        else
                        {
                            // See if theres any property we need to refer to.
                            var comArrElArr = comArrEl.Split("=>");

                            if (int.TryParse(comArrElArr[0], out var index))
                            {
                                // Traverse first
                                var rawData = token.ToObject<List<JToken>>()[index];

                                // if its 1, we assume its just an array of a primitive type
                                if (comArrElArr.Length == 1)
                                {
                                    // Retrieve the value.
                                    var rawVal = rawData.ToString();

                                    // https://stackoverflow.com/questions/23131414/culture-invariant-decimal-tryparse
                                    var style = NumberStyles.Any;
                                    if (ExponentHelper.IsExponentialFormat(rawVal))
                                    {
                                        style = NumberStyles.Float;
                                    }

                                    // If it is an exponent
                                    if (decimal.TryParse(rawVal, style, CultureInfo.InvariantCulture,
                                        out var val))
                                    {
                                        if (val > 0)
                                        {
                                            // Update it
                                            _currencyPairComponentService.UpdatePairValue(component.Id, val);
                                        }
                                    }
                                }
                                // Oh no.. non-primitive...
                                else if (comArrElArr.Length == 2)
                                {
                                    // Object-ify
                                    var rawObj = JObject.Parse(rawData.ToString());

                                    // Obtain the desired value
                                    var rawVal = rawObj[comArrElArr[1]].ToString();

                                    // As usual, update it
                                    // https://stackoverflow.com/questions/23131414/culture-invariant-decimal-tryparse
                                    var style = NumberStyles.Any;
                                    if (ExponentHelper.IsExponentialFormat(rawVal))
                                    {
                                        style = NumberStyles.Float;
                                    }

                                    // If it is an exponent
                                    if (decimal.TryParse(rawVal, style, CultureInfo.InvariantCulture,
                                        out var val))
                                    {
                                        if (val > 0)
                                        {
                                            // Update it
                                            _currencyPairComponentService.UpdatePairValue(component.Id, val);
                                        }
                                    }
                                }
                                else
                                {
                                    // Invalid
                                    return false;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }
                }
                else if (token is JObject)
                {
                    // Pump in the object
                    JObject obj = token.ToObject<JObject>();

                    // Is it the last?
                    if (comArrEl != last)
                    {
                        // let's work it out
                        // update the token
                        token = obj.SelectToken(comArrEl);
                    }
                    // Yes its the last
                    else
                    {
                        // See if theres any property we need to refer to.
                        var comArrElArr = comArrEl.Split("=>");

                        // Traverse first
                        var rawData = (string) obj.SelectToken(comArrElArr[0]);

                        if (rawData != null)
                        {
                            // if its 1, we assume its just an array of a primitive type
                            if (comArrElArr.Length == 1)
                            {
                                // Retrieve the value.
                                var rawVal = rawData.ToString();

                                // https://stackoverflow.com/questions/23131414/culture-invariant-decimal-tryparse
                                var style = NumberStyles.Any;
                                if (ExponentHelper.IsExponentialFormat(rawVal))
                                {
                                    style = NumberStyles.Float;
                                }

                                // If it is an exponent
                                if (decimal.TryParse(rawVal, style, CultureInfo.InvariantCulture,
                                    out var val))
                                {
                                    if (val > 0)
                                    {
                                        // Update it
                                        _currencyPairComponentService.UpdatePairValue(component.Id, val);
                                    }
                                }
                            }
                            // Oh no.. non-primitive...
                            else if (comArrElArr.Length == 2)
                            {
                                // Object-ify
                                var rawObj = JObject.Parse(rawData.ToString());

                                // Obtain the desired value
                                var rawVal = rawObj[comArrElArr[1]].ToString();

                                // As usual, update it
                                // https://stackoverflow.com/questions/23131414/culture-invariant-decimal-tryparse
                                var style = NumberStyles.Any;
                                if (ExponentHelper.IsExponentialFormat(rawVal))
                                {
                                    style = NumberStyles.Float;
                                }

                                // If it is an exponent
                                if (decimal.TryParse(rawVal, style, CultureInfo.InvariantCulture,
                                    out var val))
                                {
                                    if (val > 0)
                                    {
                                        // Update it
                                        _currencyPairComponentService.UpdatePairValue(component.Id, val);
                                    }
                                }
                            }
                            else
                            {
                                // Invalid
                                return false;
                            }
                        }
                    }
                }
                // iterate JValue like a JObject
                else if (token is JValue)
                {
                    // Pump in the object
                    JObject obj = token.ToObject<JObject>();

                    // Is it the last?
                    if (comArrEl != last)
                    {
                        // let's work it out
                        // update the token
                        token = obj.SelectToken(comArrEl);
                    }
                    // Yes its the last
                    else
                    {
                        var rawData = (string) obj.SelectToken(component.QueryComponent);

                        if (rawData != null)
                        {
                            // https://stackoverflow.com/questions/23131414/culture-invariant-decimal-tryparse
                            var style = NumberStyles.Any;
                            if (ExponentHelper.IsExponentialFormat(rawData))
                            {
                                style = NumberStyles.Float;
                            }

                            // If it is an exponent
                            if (decimal.TryParse(rawData, style, CultureInfo.InvariantCulture,
                                out decimal val))
                            {
                                if (val > 0)
                                {
                                    // Update it
                                    _currencyPairComponentService.UpdatePairValue(component.Id, val);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                // Something bad happened
                return false;
            }
        }
    }

    return false;
}

Какой тип ввода данных работает?

хорошо, свойство 'token' может быть таким

{
  "?xml": {
    "@version": "1.0",
    "@encoding": "UTF-8"
  },
  "gesmes:Envelope": {
    "@xmlns:gesmes": "http://www.gesmes.org/xml/2002-08-01",
    "@xmlns": "http://www.ecb.int/vocabulary/2002-08-01/eurofxref",
    "gesmes:subject": "Reference rates",
    "gesmes:Sender": {
      "gesmes:name": "European Central Bank"
    },
    "Cube": {
      "Cube": {
        "@time": "2018-12-06",
        "Cube": [
          {
            "@currency": "USD",
            "@rate": "1.1351"
          },
          {
            "@currency": "JPY",
            "@rate": "128.04"
          },
          {
            "@currency": "BGN",
            "@rate": "1.9558"
          },
          {
            "@currency": "CZK",
            "@rate": "25.890"
          },
          {
            "@currency": "DKK",
            "@rate": "7.4635"
          },
          {
            "@currency": "GBP",
            "@rate": "0.88930"
          },
          {
            "@currency": "HUF",
            "@rate": "323.75"
          },
          {
            "@currency": "PLN",
            "@rate": "4.2881"
          },
          {
            "@currency": "RON",
            "@rate": "4.6548"
          },
          {
            "@currency": "SEK",
            "@rate": "10.2355"
          },
          {
            "@currency": "CHF",
            "@rate": "1.1304"
          },
          {
            "@currency": "ISK",
            "@rate": "138.40"
          },
          {
            "@currency": "NOK",
            "@rate": "9.7028"
          },
          {
            "@currency": "HRK",
            "@rate": "7.3965"
          },
          {
            "@currency": "RUB",
            "@rate": "75.9421"
          },
          {
            "@currency": "TRY",
            "@rate": "6.0947"
          },
          {
            "@currency": "AUD",
            "@rate": "1.5745"
          },
          {
            "@currency": "BRL",
            "@rate": "4.4370"
          },
          {
            "@currency": "CAD",
            "@rate": "1.5229"
          },
          {
            "@currency": "CNY",
            "@rate": "7.8239"
          },
          {
            "@currency": "HKD",
            "@rate": "8.8669"
          },
          {
            "@currency": "IDR",
            "@rate": "16481.65"
          },
          {
            "@currency": "ILS",
            "@rate": "4.2367"
          },
          {
            "@currency": "INR",
            "@rate": "80.4950"
          },
          {
            "@currency": "KRW",
            "@rate": "1273.03"
          },
          {
            "@currency": "MXN",
            "@rate": "23.3643"
          },
          {
            "@currency": "MYR",
            "@rate": "4.7271"
          },
          {
            "@currency": "NZD",
            "@rate": "1.6517"
          },
          {
            "@currency": "PHP",
            "@rate": "60.012"
          },
          {
            "@currency": "SGD",
            "@rate": "1.5560"
          },
          {
            "@currency": "THB",
            "@rate": "37.282"
          },
          {
            "@currency": "ZAR",
            "@rate": "15.9797"
          }
        ]
      }
    }
  }
}

Метод обновления: нужен пример ввода для строки 6?

Это даст свойство @rate.

gesmes:Envelope/Cube/Cube/Cube/0=>@rate

Более простой пример:

[
  97.935,
  1745.41815607,
  97.936,
  315.65150703,
  -6.58,
  -0.063,
  97.93,
  664801.20661302,
  105.67,
  96.23
]

Строка 6 будет просто "0"

...