How can I access a nested struct data by indexing of the fields?
31 views (last 30 days)
Show older comments
Hi,
I'm trying to make loop to take some data from an url using webread. Each loop I collect a set of struct format data. Some field names are mainted (fixed) so I can use it in the loop. However, some names in struct data are specific, which difficults get them. I tried different ways of indexing but none worked.
Here an example of the loop
for i = 1%:numel(LotusID);
Prefixe = ('https://lotus.naturalproducts.net/api/search/simple?query=');
Sufixe = LTS0120864 %LotusID(i,1);
url_lotus = strcat(Prefixe,Sufixe);
html_lotus = webread(url_lotus);
end
I want access all information in this nested structure. However, I don't known the names of subfields to access and even create an indexing for them.
Here an example of the nested struct data.
html_lotus.naturalProducts.taxonomyReferenceObjects
Inside of this structure (html_lotus.naturalProducts.taxonomyReferenceObjects) there are 12 [1x1 struct]. So, I can't use an indexing because all them are [1x1 struct];
'x10_x_x_1021_NP980041X'
'x10_x_x_1021_NP900144C'
'x10_x_x_1248_CPB_x_x_57_x_x_302'
...
I want to get all information inside nested structured, but I dont know the names and I don't have indexing of them.
Specifically in this case (html_lotus.naturalProducts.taxonomyReferenceObjects.x10_x_x_1021_NP980041X) there are 3 anothers subsctructures for each one to them to then finally to get the data, properly.
How can I get this data. I tried to convert all nested into cells but didn't work
Thank you!
Alan
0 Comments
Accepted Answer
Stephen23
on 9 Feb 2023
Edited: Stephen23
on 9 Feb 2023
url = 'https://lotus.naturalproducts.net/api/search/simple?query=';
sfx = 'LTS0120864';
raw = webread(strcat(url,sfx))
"However, I don't known the names of subfields to access ..."
You can use FIELDNAMES() to get a cell array of the fieldnames:
fnr = fieldnames(raw)
You can loop over those and use dynamic field names to access to the field content:
For example the 3rd field contains this, another structure:
raw.(fnr{3})
"Inside of this structure (html_lotus.naturalProducts.taxonomyReferenceObjects) there are 12 [1x1 struct]. So, I can't use an indexing because all them are [1x1 struct];"
There are indeed 12 fields, so you can easily use the method I just showed with FIELDNAMES() and dynamic field names. Lets try it now:
sub = raw.(fnr{3}).taxonomyReferenceObjects
fns = fieldnames(sub);
for k = 1:numel(fns)
tmp = sub.(fns{k});
display(tmp)
%... do whatever you want with that data...
end
Note that there is no simple, single answer for how to process a nested structure, because how it needs to be processed depends on the structure content and its meaning. MATLAB cannot know this. For example, those 12 fields shown above each consist of a scalar sructure. But those scalar structures have different fieldnames: MATLAB cannot decide for you, if you want to process all of those scalar structures or perhaps you might need to ignore the ones that that are missing a particular field. This is something that only you know, based on your needs. This means that you need to write the code that checks and processes the data according to your needs.
0 Comments
More Answers (1)
Askic V
on 8 Feb 2023
Edited: Askic V
on 8 Feb 2023
One quick and dirty solution that includes very unpopular eval function is given here:
Prefixe = ('https://lotus.naturalproducts.net/api/search/simple?query=');
Sufixe = 'LTS0120864'; %LotusID(i,1);
url_lotus = strcat(Prefixe,Sufixe);
html_lotus = webread(url_lotus);
fields = fieldnames(html_lotus);
var_struct = struct();
for i = 1:numel(fields)
eval_stri = ['html_lotus.' fields{i}];
var_aux = eval(eval_stri);
if isa(var_aux,'struct')
fprintf ('\n%s is a cell\n',fields{i});
var_struct = var_aux;
end
end
var_struct
Now, I'm sure some of the gurus will suggest more elgant way.
But in the code abive you can see how you can use webread and how to check if the variable is a structure, how to get fieldnames and use it to read members of nested structure. Now you can make this more deep in the same way.
Anyway the code above shows you how to get the names of the fields and how to create index of them, which was your initial question.
2 Comments
Steven Lord
on 8 Feb 2023
There's no need for eval here. Use dynamic field names.
s = struct('x', 1, 'y', 2, 'z', 3)
f = 'y';
two = s.(f) % 2
Alternately if you have multiple levels of indexing you can use getfield.
nested = struct('w', 4, 'q', s)
thefields = {'q', 'z'};
three = getfield(nested, thefields{:}) % nested.q.z
See Also
Categories
Find more on Structures in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!