03-27-2021 08:24 PM
Hi there,
I'm trying to create a VI that can read in an existing populated XML, then add children to that node.
Here's the existing XML file. I want to insert children in "img" the same way that "font" and "verification" have children that hold data. All other solutions that I've looked at create a new XML file, and thus reference document types instead of node types.
I would like to just have the LabVIEW code point to the "img" node, then insert children, but it doesn't seem to be quite that simple. When I try to implement a solution, it appends a node at the end of the file:
and yields:
One path of the code successfully puts texts within a new child, and the other just creates a child.
I want to insert "imgLocation" under "img", and insert text within it.
I know my VI needs some overhauling, but can someone give me guidance?
Solved! Go to Solution.
03-28-2021 01:03 AM
I'd like to help, but not enough to recreate everything you've done (sorry!)
Can you upload your VI (or a snippet of your VI) and an example XML file? Perhaps the one from your post, but as a file rather than an image?
A zip file containing all the files, or just a collection of files is fine (but I'd guess others might prefer a zip for easier extraction to a specific directory).
A first comment on your code would be that you have two nodes being added, but they aren't linked by dataflow - that is, you don't know which of "imgLocation" or "Node" will be added first. I don't know without testing if the reference can end up with a race condition in which sometimes they aren't both reliably added...
If you're OK exporting a new file, it should be easier, but it sounds like you're not? However, I expect anything after the location you insert will have to be rewritten on disk (you probably don't have to worry about this, but I mean it would be similar to writing a new file and renaming it to overwrite the old file).
03-28-2021 08:12 PM - edited 03-28-2021 08:13 PM
Unfortunately I can't attach xml files, so here it is in text. I simply don't have enough of an understanding of exactly what each process is doing, so my blocks are largely just cobbled together based on examples that I've found so as to not get an error.
I'm not too concerned about the issue of making a new file vs. writing over the old one - I just have to change the path of where the file is saved to. I just don't understand how to parse through the XML to arrive at the node where I want to insert the new data.
<LVData
xmlns="http://www.ni.com/LVData">
<Version>20.0</Version>
<process>
<numberOfSlides>3</numberOfSlides>
<slide>
<slideNumber>1</slideNumber>
<font>
<fontType>Garamond</fontType>
<fontPresent>Yes</fontPresent>
<fontXLocation>0</fontXLocation>
<fontYLocation>3</fontYLocation>
<fontSize>24</fontSize>
<fontText>This is a placeholder</fontText>
</font>
<img></img>
<verification>
<verificationType>Check</verificationType>
<verifyValue>0</verifyValue>
<verificationMin>-12</verificationMin>
<verificationMax>12</verificationMax>
</verification>
</slide>
</process>
</LVData>
03-28-2021 09:07 PM - edited 03-28-2021 09:12 PM
Ah, after a little playing I found it.
You were close - the problem is at the "Get First Matched Node" - you've wired the Append Child methods to the "Node out" output, but you need to use the "node result" immediately below that.
Edit: I attached my modified VI, although basically it's the same as yours but with error wires connecting the nodes just in case that was the problem (it wasn't, but wanted to check).
03-28-2021 09:24 PM
There are two ways to get almost any file "attached" to the Forum:
Notice that an XML file is simply a Text File with a structure imposed by <begin> and </begin> (or "end") Tags. So you can read a line, see if it has the end-Tag that marks the place after which you want to insert your new text, insert it, then copy the rest of the file afterwards.
Another way to handle this is to simply use the XML File I/O functions to read the entire contents of the File into whatever LabVIEW data structure it encodes (the most general format likely involves nested Clusters and Arrays). Since you are adding new information, this usually involves a somewhat-changed Type, one that has a declaration (in the correct place) for the new Information you want to include in the XML file. Once you have the updated Data, open a new XML file (perhaps with a similar name, perhaps with "-Updated" added before the .XML extension) and write out the updated Data.
Bob Schor
03-29-2021 03:46 PM
I'm somewhat old school with stuff like this. I would do straight string parsing with regular expressions to modify the XML. Writing it backout to the file you could simply open the file for writing, set the file pointer to the begining and overwrite the data. Since you are adding you text would be longer than the original and therefore everything would get overwritten.
03-29-2021 03:52 PM - edited 03-29-2021 03:53 PM
@cbutcher wrote:
Ah, after a little playing I found it.
You were close - the problem is at the "Get First Matched Node" - you've wired the Append Child methods to the "Node out" output, but you need to use the "node result" immediately below that.
Edit: I attached my modified VI, although basically it's the same as yours but with error wires connecting the nodes just in case that was the problem (it wasn't, but wanted to check).
Your modified example was exactly what I was looking for! The way I was thinking about how to wire the blocks was all backwards from the "syntax" that LV wanted.
Thanks much.