Question about accessing data in a nested struct
5 views (last 30 days)
Show older comments
Hi all,
I am trying to get data from an xml file using xml2struct. Calling the struct using dot notation such as
Settings.CAFConfigurationSettings.numberOfTestPieces.Text
doesn't seem to work. Currently, I am calling on the data using the syntax
Settings.Children(20).Children.Data
where Dataset is my structure and x, y and z are integers referring to the index position within the nested structure. The problem is that sometimes the xml structure stores the same information in different positions meaning x, y and z will be different for these. For example, the "date" field might be the 3rd index (x=3) in one file, or the 2nd index (x=2) in another.
Is there a way to navigate around this please? I need to have a consistent way to gather this data because I loop through several xml files, so I need to get the same, consistent information from all the files with certainty.
I have tried to use "find" but to no avail. a sample of the files can be found here: https://www.dropbox.com/sh/ed5uv80s272mh4t/AAA1hROx8LvVeALHpqtTuSiGa?dl=0.
Thank you in advance
The code:
Accessing the data
close all
clear all
clc
%Asking the user to select the folder with the Images and Auto analysis in
startingFolder = pwd;
fprintf('Select the directory containing the Images and Auto analysis \n \n');
RawImages = uigetdir(startingFolder); %Creating the variable from the user selection
addpath(RawImages); %Ensuring matlab will follow the path
files = dir([RawImages '\AutoAnalysis\*.xml']);
numOfFiles = numel(files); %Counting number of files in the folder for looping purposes
Settings = xml2struct([RawImages '\settings.xml']); %Converting XML to structure then accessing the number of the samples from the Settings file
NumOfSamples = str2double(Settings.Children(20).Children.Data);
headings = {'Time','Temperature','Height','Area','Circumference', 'Shape Factor', 'Tip Radius', 'Base Width', 'Max Width', 'Height:Base Width Ratio', 'Height:Max Width Ratio', 'Bse Centre X', 'Base Centre Y', 'LHS Difference', 'RHS Difference'};
objectRangeEnd = strcat('O', num2str(numOfFiles));
objectRange = strcat('A2:', objectRangeEnd);
for j = 1:NumOfSamples %Getting the manually named test pieces from the settings
TestPieceName = Settings.Children(22).Children((2*j)).Children(4).Children.Data; %Creating a name variable to use when making file and folder names
Sample = ['Test Piece ' num2str(j) '-' TestPieceName];
TestPiece = zeros(numOfFiles,3); %Making an array to store the variables
for k = 1:numOfFiles %Grabbing the time and file data from the save file name
flds = {'date','bytes','isdir','datenum'}; %Reading time and temp from file
A = rmfield(files,flds); %Remove the file information that is unnecessary
codes = struct2cell(A); %Reduces the structure to only the fields required
codes = codes'; %Converts the labels in A to the format required
new = strsplit(char(codes(k)),'.'); % To remove the file type
new2 = strsplit(char(new(1)),'-'); % Splits the experimental conditions
time = str2double(new2(2));
alpha = new2(3);
alpha = char(alpha);
alpha(1) = [];
temp = str2double(alpha);
TestPiece(k,1) = time;
TestPiece(k,2) = temp;
file = [ RawImages '\AutoAnalysis\' files(k).name]; % Creating the k-th file name
DataSet = xml2struct(file); % Converting XML files to structures
datasetNum= numel(DataSet.Children);
testPieceLocation = datasetNum - NumOfSamples + j; %Indexing Height, Area, and Circumference etc.
TestPiece(k,3) = str2double(DataSet.Children(testPieceLocation).Children(end).Children('height').Children.Data); %Height
TestPiece(k,4) = str2double(DataSet.Children(testPieceLocation).Children(end).Children().Children.Data); %Area
TestPiece(k,5) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(find('circumference')).Children.Data); %Circumference
TestPiece(k,6) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(find('shapeFactor')).Children.Data); %Shape Factor
TestPiece(k,7) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(find('tipRadius')).Children.Data); %Tip Radius
TestPiece(k,8) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(5).Children.Data); %Base width
TestPiece(k,9) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(6).Children.Data); %Max Width
TestPiece(k,10) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(find('hBwRatio')).Children.Data); %hBw Ratio
TestPiece(k,11) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(find('hMwRatio')).Children.Data); %hMw Ratio
TestPiece(k,12) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(1).Children.Data); %Base Centre X
TestPiece(k,13) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(2).Children.Data); %Base Centre Y
TestPiece(k,14) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(3).Children.Data); %LHS Diff
TestPiece(k,15) = str2double(DataSet.Children(testPieceLocation).Children(end).Children(4).Children.Data); %RHS Diff
initialheight = TestPiece(1,3);
initialarea = TestPiece(1,4);
initialcirc = TestPiece(1,5);
initialSFactor = TestPiece(1,6);
initialTRad = TestPiece(1,7);
initialBW = TestPiece(1,8);
initialMWidth = TestPiece(1,9);
initialHBW = TestPiece(1,10);
initialHMW = TestPiece(1,11);
initialBaseCX = TestPiece(1,12);
initialBaseCY = TestPiece(1,13);
initialLHSDiff = TestPiece(1,14);
initialRHSDiff = TestPiece(1,15);
TestPiece(k,3) = TestPiece(k,3)/initialheight;
TestPiece(k,4) = TestPiece(k,4)/initialarea;
TestPiece(k,5) = TestPiece(k,5)/initialcirc;
TestPiece(k,6) = TestPiece(k,6)/initialSFactor;
TestPiece(k,7) = TestPiece(k,7)/initialTRad;
TestPiece(k,8) = TestPiece(k,8)/initialBW;
TestPiece(k,9) = TestPiece(k,9)/initialMWidth;
TestPiece(k,10) = TestPiece(k,10)/initialHBW;
TestPiece(k,11) = TestPiece(k,11)/initialHMW;
TestPiece(k,12) = TestPiece(k,12)/initialBaseCX;
TestPiece(k,13) = TestPiece(k,13)/initialBaseCY;
TestPiece(k,14) = TestPiece(k,14)/initialLHSDiff;
TestPiece(k,15) = TestPiece(k,15)/initialRHSDiff;
end
sampleDirectory = fullfile(RawImages); %file creation
filename = fullfile(sampleDirectory, ['Results.xls']); %Creating the filename to put the excel file in the appropriate folder
writecell(headings, filename, 'Sheet', Sample, 'Range', 'A1:O1');
writematrix(TestPiece, filename, 'Sheet', Sample, 'Range', objectRange);
end
3 Comments
Accepted Answer
per isakson
on 27 Jan 2021
Edited: per isakson
on 27 Jan 2021
It is impossible (for me) to help based on the little information that you provide. Here (R2018b) it works fine.
>> sas = xml_read( '..\settings.xml') % the xml-file is in the parent folder
sas =
struct with fields:
version: '1.3.6213.31983'
date: '2020-03-18T13:44:48.0887698+00:00'
testStandardIndex: 'CoalAsh'
startCaptureTemperature: 400
endCaptureTemperature: 1550
temperatureRamp: 7
temperatureInterval: 1
standbyTemperature: 30
backlightOffTemperature: 710
numberOfTestPieces: 6
testPiece: [1×1 struct]
cal: [1×1 struct]
gridDisplayEnable: 1
activeTestPiece: 1
ATTRIBUTE: [1×1 struct]
>> sas.activeTestPiece
ans =
1
I propose that you use XML Notepad (free, Windows) to inspect the structure of the xml-files. Be sure not to reference non-existing fields.
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/501658/image.png)
0 Comments
More Answers (0)
See Also
Categories
Find more on Matrix Indexing 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!