Hi kent,
we have this thread where you asked the question.
Following an example about how to read the data from a json like that. I've also add the case when you have the same keys in your json so you can loop over the elements.
There is no way of accessing directly a element in the json file.
#include "maxon/apibase.h"
#include "maxon/errorbase.h"
#include "maxon/errortypes.h"
#include "maxon/parser.h"
#include "maxon/application.h"
#include "c4d_general.h"
// This function read a json file and return the content as a datadictionary.
static maxon::Result<const maxon::DataDictionary> ReadJSONFile(const maxon::Url& jsonfFile)
{
iferr_scope;
CheckArgument(jsonfFile.IoDetect() != maxon::IODETECT::NONEXISTENT, "File doesn't exist"_s);
// Create the parser for the json file and read it.
maxon::BaseArray<maxon::DataDictionary> jsonArray;
maxon::ParserRef parser = maxon::ParserClasses::JsonParser().Create() iferr_return;
parser.Read(jsonfFile, maxon::PARSERFLAGS::NONE, maxon::GetUtf8DefaultDecoder(), jsonArray) iferr_return;
if (jsonArray.IsPopulated())
return jsonArray[0];
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION, "Json file couldn't be read"_s);
}
static maxon::Result<void> pc13625(BaseDocument* doc)
{
iferr_scope;
/*
this function read the following json file:
{
"a": [{
"b": "bbb",
"c": "ccc"
},
{
"d": "ddd",
"e": "eee"
}
],
"b" : [{
"name" : "one",
"value" : 1
},
{
"name" : "two",
"value" : 2,
"valueasfloat" : 2.0
}
]
}
The element in the array "a" do not share the same keys. The first one have b and c, the second d and e. So we have to access all element one by one.
In the array "b" the elements share the same keys so we can loop over them.
*/
const maxon::Url myJsonFile = maxon::Application::GetUrl(maxon::APPLICATION_URLTYPE::CURRENT_MODULE_DIR).Append("res"_s).Append("jsonexample.json"_s) iferr_return;
const maxon::DataDictionary content = ReadJSONFile(myJsonFile) iferr_return;
MAXON_SCOPE
{
// Reading array "a" we can't loop all the element because they have different keys.
maxon::BaseArray<maxon::Data> arrayA = content.Get<maxon::BaseArray<maxon::Data>>("a"_s) iferr_return;
const maxon::Data& firstElement = arrayA[0];
// we know the elements in the array are dictionary so we can convert Data to Dictionary
maxon::DataDictionary bAndc = firstElement.Convert<maxon::DataDictionary>() iferr_return;
const String b = bAndc.Get<String>("b"_s) iferr_return;
const String c = bAndc.Get<String>("c"_s) iferr_return;
const maxon::Data& secondElement = arrayA[1];
maxon::DataDictionary dAnde = secondElement.Convert<maxon::DataDictionary>() iferr_return;
const String d = dAnde.Get<String>("d"_s) iferr_return;
const String e = dAnde.Get<String>("e"_s) iferr_return;
ApplicationOutput("value in the json are b:@ c:@ d:@ e:@", b, c, d, e);
}
MAXON_SCOPE
{
// reading array "B" we can loop over all elements because they share the same key.
maxon::BaseArray<maxon::Data> arrayB = content.Get<maxon::BaseArray<maxon::Data>>("b"_s) iferr_return;
for (maxon::Data& element : arrayB)
{
maxon::DataDictionary dict = element.Convert<maxon::DataDictionary>() iferr_return;
const String name = dict.Get<String>("name"_s) iferr_return;
const Int value = dict.Get<Int>("value"_s) iferr_return;
// As the value as float is optionnal, we need a different path if the value doesn't exist.
iferr (const Float valueAsFloat = dict.Get<Float>("valueasfloat"_s))
{
ApplicationOutput("the element with name @ have the value @", name, value);
continue;
}
ApplicationOutput("the element with name @ have the value @ and as float @", name, value, valueAsFloat);
}
}
return maxon::OK;
}
Cheers,
Manuel