04-22-2015 05:06 AM
Hello LabVIEW community,
let's consider the following situation:
- I have a type definition enum, which is susceptible to offer further options in the future (but *not* to modify or delete any!). In the worst case, the options would be reordered.
- I save this enum (either directly or as an element of an array/cluster/class) as XML using the 'Flatten to XML' [and 'Write to XML File' VIs].
- I then read the XML file using the ['Read from XML file' and] 'Unflatten from XML' VIs.
Is there any way to ensure the saved file can be read in the future when the type definition used in the program evolves in time? I am *not* bound to the [Un]flatten XML VIs and would be happy to change to something else offering a future proof solution.
I have attached a minimal example demonstrating what I would like to achieve.
Does anybody have a clue for my issue?
Best regards,
Mat
04-22-2015 05:50 AM
I can't see your code as I only have 2012 on this machine, but from your description I'm trying to understand what you are trying to do. It seems a little wiggy to me - the point of enums is that they are defined and don't change, and "in the worst case, they would be re-ordered" is going to break all sorts of things (case statements, etc?) What is your goal here?
If you have, for example, a user selection from a list (eg. an enum, 'A', 'B', 'C') and you want to persist this user choice to a file so it can be later recalled then it could be quite simple. The enum value is written to the file as an integer, and when recalled you read the integer and cast it into the enum type (or unflatten from xml which effectively does the same) and all should be well. Even if you later edit your source code to add more enum values, the fact that it is stored as an integer means that as long as you don't remove values this should not be a problem.
If on the other hand you re-order the enum elements you will have a whole world of trouble! Why would you want to?
If you want more flexibility (to add, remove, re-order) then I would suggest saving the value as a string, and in your read-file routine you will need some intelligent parsing to translate the read string into a value that your program can use. A lot depends on how the program uses this value - in case statements, in direct comparisons, as a numeric value, etc.
Kind of curious about your application...
04-22-2015 06:42 AM
I am building an application which loads OOP-based measurement classes using the factory pattern. Depending on the DUT reference I load dynamically different measurements classes.
So far, I have listed the available measurements in an enum. To each DUT reference corresponds an array of that given enum, listing the measurement and their relative order. It is this information that gets saved as XML. As I extend the list of available measurements, my enum changes...and I can no longer load my XML file, even if I do not reorder the enum because not only the integer/enum index, but also the list of enum choices is saved. Accordingly at laod time, the unflatten from xml function throws me an error 1105.
04-22-2015 07:00 AM
Ah, I see.
I forgot that xml saves the enum choices in the file.
You could try casting the enum as an integer before saving and casting it back on read. You would need to re-factor the data structure you feed to the xml vi to use int instead of the enum type (you could use an intermediate data structure if you want to keep the enum in the rest of the program). I would try to avoid re-ordering the tests. If you must then my earlier suggestion about using a string and parsing might work.
Or make your own custom file structure and write the array elements explicity using the file write/read vis - again, write an int and cast back on read - you then have full control over how the data from the file maps back to your enum.
04-22-2015 07:15 AM - edited 04-22-2015 07:16 AM
Don't save the enum as an enum. Save the value as a string, then run that string through scan from string to generate an enum with the given value.
Mike...
04-22-2015 07:33 AM
Thanks for the comments.
I have considered converting to a string, BUT...:
- I have so far relied on the [Un]flatten XML VIs because they are very generic: bundle your data in a cluster, flatten, save, load unflatten, unbundle, and voilà!
- "run that string through scan from string to generate an enum with the given value" that is a hot solution candidate! It requires that I know the target enum type though... i.e. a tailored solution.
I wish I could build a mechanism which keeps as generic as the [Un]flatten XML VIs are. For that I need to somehow save the reference to the target enum... is it at all possible once the program is compiled?
04-22-2015 07:46 AM
04-22-2015 08:39 AM
Yes, you are right, it has to be a two-layered solution.
I do not understand the "Also on the receiving side you don't have to know the specific enum, all you need is an enum with a matching value.".. Or rather I think I understand it, but is there any fine idea behind it? I could of course gather all the enum (only 3 kinds could land in the XML), but two of them have overlapping value text. These are the Meter and Source type for SMU units:
Meter:
- Voltage
- Current
- Resistance
Source:
- Voltage
- Current
Unfortunately I cannot blindly search and return the first match... 😞 I have to further think about it.
Thanks anyway!
Mat
04-22-2015 09:22 AM