如何在 C++ Builder 中使用 TJSONObject class 获取 JSON 值?
How to get JSON value using TJSONObject class in C++ Builder?
我无法使用 TJSONObject
获得某些 JSON 值,我收到错误 Access violation at address xxxxxxxxx
。
我在使用 JSON 文件中的键名获取所需值时遇到问题,
我目前正在使用 TRESTClient
、TRESTRequest
、TRESTResponse
从网络获取 JSON 数据,我使用相同的 JSON URL 和 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"
]
}
}
]
您显示的 JSON 是一个对象数组,而不是单个对象,就像您的代码假设的那样。所以 TJSONObject::ParseJSONValue()
会 return 一个 TJSONArray
instead of a TJSONObject
,因此你在评论中断言 "JSONObject is valid" 可能是真的是不可能的,因为 dynamic_cast<TJSONObject*>
会失败并且return NULL,您的代码没有检查它。您没有显示 FULL 错误消息,但如果显示 "read of address 00000000",则表明正在访问 NULL 指针。
另外,TJSONObject::Get()
is deprecated. To retrieve a value by name, use TJSONObject::GetValue()
。
此外,如果您使用 TRESTResponse::JSONValue
property instead of the TRESTResponse::JSONText
属性,TRESTResponse
可以为您解析 JSON。
此外,如果您的代码是使用非基于 ARC 的 C++ 编译器之一编译的,那么您正在泄漏分配的 TJSONObject
。
话虽如此,试试这个:
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";
}
我无法使用 TJSONObject
获得某些 JSON 值,我收到错误 Access violation at address xxxxxxxxx
。
我在使用 JSON 文件中的键名获取所需值时遇到问题,
我目前正在使用 TRESTClient
、TRESTRequest
、TRESTResponse
从网络获取 JSON 数据,我使用相同的 JSON URL 和 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"
]
}
}
]
您显示的 JSON 是一个对象数组,而不是单个对象,就像您的代码假设的那样。所以 TJSONObject::ParseJSONValue()
会 return 一个 TJSONArray
instead of a TJSONObject
,因此你在评论中断言 "JSONObject is valid" 可能是真的是不可能的,因为 dynamic_cast<TJSONObject*>
会失败并且return NULL,您的代码没有检查它。您没有显示 FULL 错误消息,但如果显示 "read of address 00000000",则表明正在访问 NULL 指针。
另外,TJSONObject::Get()
is deprecated. To retrieve a value by name, use TJSONObject::GetValue()
。
此外,如果您使用 TRESTResponse::JSONValue
property instead of the TRESTResponse::JSONText
属性,TRESTResponse
可以为您解析 JSON。
此外,如果您的代码是使用非基于 ARC 的 C++ 编译器之一编译的,那么您正在泄漏分配的 TJSONObject
。
话虽如此,试试这个:
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";
}