LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Modify an element within an XML file

Hi,

I am struggling, again!!

 

I need to programmatically change different items in any xidml file, example attached, My_Work_01.xidml.(renamed to My_Work_01.txt to allow upload to the forum)


I need to programmatically add/remove/change serial numbers.


Using an XPath command, //Location//SerialNumber I get 3 elements, each with its own attribute.

 

I have tried xmlTree and XMLSample from the examples but I cannot, do not understand how to, modify them to do what I need to do.

 

I need to get each of the serial numbers, modify them, and write them back in and save the file.

 

Any help or direction?

Thanks

Simon

0 Kudos
Message 1 of 11
(4,453 Views)

Hello Simon,

using XMLSample I was able to perform what you want.

Browse to your file and open it, next in "Child element list" box double click on Instrumentation (or click on View child element which is the same), next InstrumentSet next Instrument. Here you can look at element properties where you find the instrument name; next double click on Manufacturer and Serial Number where you can write down what you want in the highlighed field:

 

XMLsample.png

 

Next you can press Save Xml to have the file updated.

 

Looking at the string control callback ValChanged you will see that to update the XML content CVIXMLSetElementValue () function is used. The problem can be to obtain the correct element index, but following the path I traced in the code you can see how to obtain it (UpdateChildren function shows you how to obtain the set of children and operate on it. CVIXMLGetChildElementByTag can also be of help to directly locate the element you want).



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 11
(4,447 Views)

Hi,

Thanks for that, unfortunately I cannot get to open the file programmatically, it has been a sad day/week.

 

I have a sample code to make an xml file, CVIXML_Example, at the end of which I programmatically change companyChild elements value. The file, srm.xml, is then saved and closed, a much smaller and simple file.

 

Then I try to open Copy_of_srm.xml to read the same element, which I know has a different value but I get the last value used to write to srm.xml.(from .xml to .txt)

 

char filePath[MAX_PATHNAME_LEN] = "C:\\CVI\\XML\\CVIXML_EXAMPLE\\Copy_of_srm.xml";

CVIXMLDocument document;

CVIXMLElement curElem;

CVIXMLElement companyChild = 0;

char Value_01[100];

                CVIXMLLoadDocument (filePath, &document);

                CVIXMLGetRootElement (document, &curElem);

                CVIXMLGetElementValue (companyChild, Value_01);

 

Thanks

Simon

Download All
0 Kudos
Message 3 of 11
(4,433 Views)

Sorry Simon, I don't understand. What's wrong with your code? I can't see anything clearly wrong.

Are you getting some error? Which one? Or aren't you getting expected result? Can you post a functional project so that we can test?



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 11
(4,424 Views)

Hi,

Thanks for the interest.

 

I am not getting expected result.

 

The original example will make a file srm.xml with elements and values at the end of which I read companyChild, modify it to “got from File”, write, save and do a DiscardDocument , so far so good.

 

Now I apparently open Copy_of_srm.xml, no errors seen, saved previously with unique modifications, do a CVIXMLGetElementValue of companyChild but this value read is that seen in srm.xml.

 

Attached is what I believe you are looking for.

 

Thanks

Simon

0 Kudos
Message 5 of 11
(4,416 Views)

As far as I can understand, the problem here is that you are reusing companyChild element value while reading a new file. You should rebuild the element chain to read back the correct element value: after the following calls value_01 holds the correct value

 

// Read back informations from a different file
CVIXMLLoadDocument (filePath, &document);
CVIXMLGetRootElement (document, &root);

// Trace down to the correct element
CVIXMLGetChildElementByTag (root, "MessageHeader", &curElem);
CVIXMLGetChildElementByTag (curElem, "CompanyName", &curElem);
CVIXMLGetChildElementByTag (curElem, "CompanyChild", &companyChild);

CVIXMLGetElementValue (companyChild, Value_01);

 

Remember to dispose of all elements you are using at function end: if you enable resource tracking (set Options >> Build options >> Debugging level to Extended) you will see which resources were not properly freed in the program (look at Resource Tracking window at program end).

 

Finally, instead of GetSystemTime + sprintf wouldn't be simpler using TimeStr ()?



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 6 of 11
(4,409 Views)

Hi,

 

Cool, kudos for that.

 

Also thanks for the TimeStr tip.

 

As is the case with me it is the norrow end of the wedge.

 

Returing to the orginal problem finding the correct serial number in My_Work_01.xidml.(renamed to My_Work_01.txt to allow upload to the forum) which is attached to the first posting.

 

The serial number in question, for example is found at:

xidml/Instrumentation/InstrumentSet/Instrument/Instruments/Location[@Name='6']/Instrument/Manufacturer/SerialNumber.

 

Is this a case of drilling down as you have already shown ?

 

Any hints/direction as how to handle Location[@Name='6'] of this path?

 

Thanks

Simon

 

 

0 Kudos
Message 7 of 11
(4,401 Views)

In my opinion, once you have found your way to xidml/Instrumentation/InstrumentSet/Instrument/Instruments you must enumerate all elements (like for example UpdateChildren () function in XMLsample) and look at attribute "Name" for each of them, processinig the element that corresponds to your selection criteria.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 8 of 11
(4,391 Views)

Hi,

 

Can I get help with the following?

 

When I drill down to

xidml/Instrumentation/InstrumentSet/Instrument/Instruments/Location these are 3 elements.

 

Each of these elements has a child, Instrument, while each of these have a child call Manufacturer, which in turn has child PartReference.

 

I am able to get the data for PartReference located under Manufacturer located under the FIRST Instrument.

 

I cannot see a way to move back up to Instrument and go to the SECOND occurrence and then once more drill down to PartReference again.

 

My question is

  1. How to move back up a tree and down the next branch once there.
    CVIXMLDiscardElement (curElem); does not appear to do it for me to go up!!

2.How to display what child I am presently at.
CVIXMLGetElementValue (curElem, value); does not appear to do it for me!!

 

As always thank for your time

Simon   

0 Kudos
Message 9 of 11
(4,378 Views)

As I told you, you must pause one step earlier than "Location" and process all children finding the correct one.

I am attaching a modified version of your sample project with a new function that performs this task. The function properly dispose of allocated elements.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 10 of 11
(4,369 Views)