03-04-2013 06:04 PM
Does anyone know how to get around the problem of updating the type definition breaks the XML parsing ? In other words, you save a cluster as XML, then add some more variables. When you try to reload the old data, the parsing fails. Is there any way around this?
03-05-2013 10:20 AM
Yes I believe GXML versioning will help.
Look at the example "GXML Versioning.vi". It is available from the pallette in User Libraries > GXML > Examples.
Basically you insert a version string onto the GXML text. Your parsoning VI first looks at the version and decides which typedef you want to use to decode the string.
Is this what you are looking for?
Jeff Tipps
S&V Systems Engineer
03-05-2013 02:15 PM
Yes, that looks like a solution, thanks!
08-22-2013 01:49 PM
I tried placing a table control inside my GXML cluster and found that it is unsupported. Turns out that while the data type of a table control is a 2-D string array, there is no way to name the array item (i.e. cell names are blank). So, gxml_NameFilter VI raises error 537501 since the underlying data type (i.e. string) has no name.
09-02-2013 03:56 PM
I'm trying to get my head around XML and have been "comparing" LabVIEW XML, GXML, and EasyXML. To me, GXML looks like the most "user-friendly" and "user-readable", but there's a (fixable) bug --
There apparently is a restriction on the (forgive me if I use the wrong terminology here) "tags" in XML -- they can't have embedded spaces nor non-alphanumeric characters except hyphen, period, or underscore. GXML does a "rational" thing with spaces, replacing them with underscores (as does EasyXML), but "chokes" on parentheses (EasyXML leaves them out of the tag).
It would be easy to make GXML "correct" such "illegal" internal characters by simply omitting them. For example, a name such as "Rate (Hz)" would become "Rate_Hz", the space replaced by an underscore and the parentheses removed.
To "patch" GXML, one needs to modify gxml_NameFilter. Replace the test for a character other than one of the legal characters with a Search and Replace String function (coming before the tests) that simply removes the illegal character(s). I've attached a snippet.
09-03-2013 08:49 AM - edited 09-03-2013 08:51 AM
I've added the ability to handle a few extra characters and add new ones as I need them by making the following edit. Also, see attached for the VI.
09-03-2013 09:00 AM
I've been studying the similarity and differences between "LabVIEW XML" (the XML distributed with LabVIEW 2012), GXML, and EasyXML. There are many things about GXML that I like, not the least of which is that we can "poke around inside" and begin to understand what XML really is and how we can use it.
I'm thinking of using XML to create a Header file for a data collection routine, one which can run for, say, an hour, and consists of doing a series of Trials. The Header has two kinds of data -- Experiment data, written once and "global" to the entire session, and Trial data, one element per Trial.
One thing of concern is the desire to not lose data because of a glitch (dare I say a Programming error?) on, say, Trial 17 that shuts down the Real-Time side. One way I was thinking of "safe-guarding" the data was to close the data file at the end of each trial (preserving the data), re-open it immediately, positioning myself at the end-of-file (a quick operation), and continuing from there.
One "gotcha" is that XML, and GXML in particular, writes its own header, plus "wraps" the XML in a Root Element. However, the flexibility of GXML makes it possible to "have my cake and eat it, too", with only a little effort. Here's how I envision using a slightly-modified GXML --
Write an Action Engine with the following actions: Create XML, Add XML to File, Reopen XML, and Close XML. This Action Engine would take over the duties normally served by gxml_WriteXMLtoFile and gxml_Generator. They'd work as follows:
Create XML: Open/Create the XML File and write the XML Header (code from gxml_WriteXMLtoFile), the Version (code from gxml_Generator) and the GXML_Root (code from gxml_Generator). Note this assumes the Version should be written only once, at the beginning of the XML file; if this assumption is wrong, leave the code in gxml_Generator.
Add XML to File: Convert the input to XML (code from gxml_Generator, minus the Version information and minus wrapping GXML_Root around the XML string) and write it to the opened file.
Reopen XML: Close the XML file (without writing </GXML_Root>, open in append mode, position at the end of file.
Close XML: Write </GXML_Root> and close the file.
It seems to me that this sequence allows me to write a fully-compliant XML file a piece at a time. In particular, I can Create XML, Add XML to File (passing in the Experiment data), then for every trial, do the sequence Add XML to File (passing in the Trial data for that trial) + Reopen XML. At the conclusion of the Experiment, do a Close XML.
What happens if there is a crash, and the final </GXML_Root> isn't written? Simply open the existing XML file (might want another Action called Open Partial XML File) and then call Close XML.
Any comments on this? I'm impressed with the clarity of the GXML "package", and the ease with which it lends itself to extending functionality while maintaining internal consistency with its own Standard.
BS
09-03-2013 09:22 AM
How would you read the data back as a known cluster if you are appending new data? Would the new trial-appended-data be in array form? Also, re: my post above: I like the idea of auto-handling all characters. Maybe merge our ideas and replace all forbidden characters with an underscore instead to prevent the the chance of collisions?
09-03-2013 11:57 AM
@Jeff_T. wrote:
I think my approach to "un-concantination" was the search parser. I can see this VI being useful however when you need to use the quick parser.
Thank you
Jeff Tipps - S&V Systems Engineer
I'm working on something similar. As I noted in an earlier post, I'm trying to deal with an XML file that basically has two kinds of elements, an Experiment cluster and one or more (determined at run time) Trial clusters. I'd like to write them as they occur, and am working on an Action Engine that will let me do that (I've just tested it, and it gives an identical XML file with the "legal" GXML VIs.
The one "catch" is that there are now multiple Trial clusters in the XML file, not encased in an Array tag. However, it seems to me that the routines used in the Search Parser also can return (but presently do not) the "rest of the XML string". So if I "know" (because I designed the scheme) that there are multiple Trial elements, I could have a While loop that was fed the initial full XML string into an input Shift Register, asked to parse out a Trial, and put the "rest of the XML string" in the output Shift Register, stopping when the Parse failed to match anything.
The end result is that I'd get out an Array of Trial, even though I wrote Trial elements one-at-a-time, instead of all-at-once-in-an-array.
I hope to test this "soon".
Bob Schor
09-03-2013 12:13 PM
@LabBEAN wrote:
How would you read the data back as a known cluster if you are appending new data? Would the new trial-appended-data be in array form? Also, re: my post above: I like the idea of auto-handling all characters. Maybe merge our ideas and replace all forbidden characters with an underscore instead to prevent the the chance of collisions?
My idea about how to treat trial-appended-data is to "improve" the Search Parser. If I use it now on an XML file with multiple Trials, it returns (as you'd expect) the first Trial it finds. Buried in the GXML Parsing code (but not yet brought out to a connector) is the "Rest of the XML string". If we had access to this, and placed it in a Shift Register so we could do another Search Parse on the remainder, we could extract all of the Trials, even though they occur one-at-a-time, and might not even be concatenated! I haven't tested this yet, but give me a day or so ...
The trouble with replacing multiple characters with underscores is you can end up with lots of underscores. Specifically, the label "Rate (Hz)" would become "Rate__Hz", which seems "excessive". I got the idea of simply "dropping" the not-allowed characters by seeing how EasyXML handled this issue (LabVIEW XML didn't care, as it wasn't used as an Element name, and GXML gave an error on encountering the parentheses).
I think "eliminating invalid stuff" is marginally preferable to "replacing with _".
Thanks for the feedback! I'd be happy to "share".
Bob Schor