Как получить значение JSON, используя класс TJSONObject в C ++ Builder? - PullRequest
0 голосов
/ 08 апреля 2019

Я не могу получить определенное значение JSON с помощью TJSONObject, я получаю ошибку Access violation at address xxxxxxxxx.

У меня проблема с получением нужного значения с использованием его имени ключа из файла JSON, сейчас я нахожусьиспользуя TRESTClient, TRESTRequest, TRESTResponse для получения данных JSON из Интернета, я использовал тот же URL-адрес JSON с Javascript и работает нормально, но в C ++ Builder это не так, он просто показывает ошибку Access violation at address xxxxxxxxx blablabla, это происходит, когда я пытаюсь получить определенное значение JSON, используя его имя, например, для EX: "name": "sparky", но когда я получаю полный файл JSON, он успешно выполняется без ошибок.

Код:

TJSONObject *JSONObject = new TJSONObject();

__try
{
    RESTClient1->BaseURL = "https://learnwebcode.github.io/json-example/animals-1.json";
    RESTRequest1->Execute();
    JSONObject = dynamic_cast<TJSONObject*>( TJSONObject::ParseJSONValue(RESTResponse1->JSONText) ) ;
    TJSONPair *pair = JSONObject->Get("name");
    Memo1->Text = pair->JsonValue->ToString();

}
__finally
{
    delete JSONObject;
}

ОБНОВЛЕНИЕ: Это файл JSON, из которого я хочу получить значения.

[
    {
    "name":"Meowsy",
    "species":"cat",
    "foods":
    {
      "likes":
      [
        "tuna",
        "catnip"
      ]
,
      "dislikes":
      [
        "ham",
        "zucchini"
      ]
    }
  }
,

  {
    "name":"Barky",
    "species":"dog",
    "foods":
    {
      "likes":
      [
        "bones",
        "carrots"
      ]
,
      "dislikes":
      [
        "tuna"
      ]
    }
  }
,

  {
    "name":"Purrpaws",
    "species":"cat",
    "foods":
    {
      "likes":
      [
        "mice"
      ]
,
      "dislikes":
      [
        "cookies"
      ]
    }
  }
]

1 Ответ

0 голосов
/ 08 апреля 2019

JSON, который вы показали, - это Массив объектов, а не ОДИН ОБЪЕКТ, как предполагает ваш код.Таким образом, TJSONObject::ParseJSONValue() вернет TJSONArray вместо TJSONObject, и, таким образом, ваше утверждение в комментариях о том, что «JSONObject действителен», не может бытьЗначение true, поскольку dynamic_cast<TJSONObject*> завершится с ошибкой и вернет NULL, который ваш код не проверяет.Сообщение об ошибке FULL не отображалось, но если оно говорит «чтение адреса 00000000», это является хорошим признаком того, что осуществляется доступ к указателю NULL.

Кроме того, TJSONObject::Get()устарела.Чтобы получить значение по имени, используйте TJSONObject::GetValue().

Кроме того, TRESTResponse может проанализировать JSON для вас, если вы используете TRESTResponse::JSONValueсвойство вместо TRESTResponse::JSONText свойство.

Кроме того, вы теряете выделенное TJSONObject, если ваш код скомпилирован с использованием одного из компиляторов C ++, не основанных на ARC.

С учетом сказанного попробуйте следующее:

RESTClient1->BaseURL = "https://learnwebcode.github.io/json-example/animals-1.json";
RESTRequest1->Execute();

Memo1->Clear();

TJSONValue *JSONValue = RESTResponse1->JSONValue;
if (JSONValue)
{
    if (TJSONArray *JSONArray = dynamic_cast<TJSONArray*>(JSONValue))
    {
        for (int i = 0; i < JSONArray->Count; ++i)
        {
            TJSONObject *JSONObject = dynamic_cast<TJSONObject*>(JSONArray->Items[i]);
            if (JSONObject)
            {
                TJSONValue *JSONObjectName = JSONObject->GetValue("name");
                if (JSONObjectName)
                    Memo1->Lines->Add(JSONObjectName->Value());
            }
        }
    }
    else if (TJSONObject JSONObject = dynamic_cast<TJSONObject*>(JSONValue))
    {
        TJSONValue *JSONObjectName = JSONObject->GetValue("name");
        if (JSONObjectName)
            Memo1->Text = JSONObjectName->Value();
    }
    else
    {
        Memo1->Text = "Ignoring unsupported JSON value type";
    }
}
else
{
    Memo1->Text = "JSON not parsed";
}
...