Components

cancel
Showing results for 
Search instead for 
Did you mean: 

Reference Library for Converting Between LabVIEW and XML Data (GXML)

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?

0 Kudos
Message 71 of 132
(6,025 Views)

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

0 Kudos
Message 72 of 132
(6,015 Views)

Yes, that looks like a solution, thanks!

0 Kudos
Message 73 of 132
(6,005 Views)

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.


Certified LabVIEW Architect
TestScript: Free Python/LabVIEW Connector

One global to rule them all,
One double-click to find them,
One interface to bring them all
and in the panel bind them.
0 Kudos
Message 74 of 132
(5,767 Views)

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.

GXML Name Filter.png

0 Kudos
Message 75 of 132
(5,726 Views)

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.

 

 

gxml_NameFilter_added chars.png

 

 


Certified LabVIEW Architect
TestScript: Free Python/LabVIEW Connector

One global to rule them all,
One double-click to find them,
One interface to bring them all
and in the panel bind them.
0 Kudos
Message 76 of 132
(5,716 Views)

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

Message 77 of 132
(5,710 Views)

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?


Certified LabVIEW Architect
TestScript: Free Python/LabVIEW Connector

One global to rule them all,
One double-click to find them,
One interface to bring them all
and in the panel bind them.
0 Kudos
Message 78 of 132
(5,708 Views)

@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

 

0 Kudos
Message 79 of 132
(5,696 Views)

 

@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

0 Kudos
Message 80 of 132
(5,694 Views)