- Preprocess the read struct first to convert the logical variables back -- unfortunately, to do this you'll have to have a standalone list of those to apply the conversion to since on input, they're now strings, or search for the string true/false through the whole struct;
- Use numeric variables instead;
- Use save/load
readstruct/writestruct changes boolean value true to "true"
10 views (last 30 days)
I am working on a MATLAB app at the moment. Some user controllable settings need to be preserved over restarting the app. During runtime these settings (statuses of buttons, text areas and checkboxes) are saved in a struct. On exiting the app, the struct is written to the hard drive of the PC using the function writestruct.
On startup, the app is loading the created XML file using readstruct. However, the values of the checkboxes (either logical true or false) are not read/saved correctly. Logical values are converted to strings.
Code example for reading/writing the struct to xml:
file = uiputfile('\Path\to\File\*.xml','Save');
file = uigetfile('\Path\to\File\*.xml');
app.Settings = readstruct(file,"FileType","xml");
While debugging, I tried to restore the settings during runtime with the generated struct, which worked as intended.
Thank you for your help!
I attached the generated XML file as an M file because I'm not allowed to upload files with the XML extension…
dpb on 28 Sep 2022
Edited: dpb on 28 Sep 2022
Should be able to test this out on local machine...
>> s.M1.Normal.enabled=true; % trial struct with logical variable
>> s.M1.Normal.enabled % it is a logical, indeed
>> clear s
struct with fields:
M1: [1×1 struct]
>> s.M1.Normal.enabled % and XML does turn it into text on scanning back in
Let's see what was in the file...
>> type testit.xml
<?xml version="1.0" encoding="UTF-8"?>
There's nothing to indicate that field 'enabled' is a logical variable; I don't know enough about XML to be able to glean whether that's somehow specifiable in the attributes stuff it talks about or not.
The doc says it's supposed to read in as the type, but since it's all an ASCII text format, unless there's something that tells it to read it as a logical and interpret the strings 'true/false', it's going to do what it did.
Workarounds I see --
The last workaround...
>> s.M1.Normal.enabled=true; % recreate the test struct
>> save('testit.mat','s') % save it to a .mat file
>> whos -file testit % see what's on disk
Name Size Bytes Class Attributes
s 1x1 505 struct
>> clear s % see what we get on reading
>> load testit
>> s.M1.Normal.enabled % and, indeed, it is the logical as expected
Somebody who knows the ins and outs of XML may be able to make it work as you would like or it may be a bug in the implementation that it doesn't recognize the logical type.
The second alternative isn't too awful bad, probably, although you may have to change some code constructs to cast a logical result to numeric on calculation; the usage can stay the same as it's a comparison to 0|1 as the internal storage.
I'd take the easy way out and just use the .mat file, meself, unless you really think you're going to try to do something with these as human-readable.