How can I access a nested struct data by indexing of the fields?
    16 vues (au cours des 30 derniers jours)
  
       Afficher commentaires plus anciens
    
    Alan Cesar Pilon Miro
 le 8 Fév 2023
  
    
    
    
    
    Modifié(e) : Stephen23
      
      
 le 9 Fév 2023
            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 commentaires
Réponse acceptée
  Stephen23
      
      
 le 9 Fév 2023
        
      Modifié(e) : Stephen23
      
      
 le 9 Fév 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 commentaires
Plus de réponses (1)
  Askic V
      
 le 8 Fév 2023
        
      Modifié(e) : Askic V
      
 le 8 Fév 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 commentaires
  Steven Lord
    
      
 le 8 Fév 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
Voir également
Catégories
				En savoir plus sur Structures dans Help Center et File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



