09-29-2011 04:37 PM
HELP.
I am having problems creating this XML schema in CVI.
In particular, the creation of <chassis> and <slot> tags throws an error.
ie.
<chassis1> does not start the container, </chassis1> starts the container and there is no subsequent closing element (ie </chassis1>)
Could one provide example code to resolve my problem?
TIA.
<?xml version="1.0" ?>
<config1>
<chassis1>
<slot1>
<element3>VALUE</element3>
<element4>VALUE</element4>
<element5>VALUE</element5>
</slot1>
<slot2>
<element7>VALUE</element7>
<element8>VALUE</element8>
<element9>VALUE</element9>
</slot2>
</chassis1>
<chassis2>
<slot1>
<element3>VALUE</element3>
<element4>VALUE</element4>
<element5>VALUE</element5>
</slot1>
<slot2>
<element7>VALUE</element7>
<element8>VALUE</element8>
<element9>VALUE</element9>
</slot2>
</chassis2>
</config1>
Solved! Go to Solution.
09-30-2011 11:20 AM
ChetK,
What error message is it throwing, and can you post a snippet of your code which is throwing this error?
Regards,
Kyle Mozdzyn
Applications Engineering
National Instruments
09-30-2011 01:45 PM
Thank you for looking into this:![]()
I get: line 95: XML Error: -2147352567
#include "cvixml.h"
#include <userint.h>
#include <formatio.h>
#include <ansi_c.h>
#include <cvirte.h>
void CreateXML(void);
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
CreateXML();
return 0;
}
void CreateXML()
{
/* Desired XML Schema
<Rack> <-rootElem*
<Chassis0> <-Elem1*
<Fan1Present>0</Fan1Present>
<Fan2Present>1</Fan2Present>
<Fuse1>0</Fuse1>
<Fuse2>0</Fuse2>
<Slot0> <-Elem2*
<Board0>1</Board0> <-Elem3*
<Board1>0</Board1>
<Board2>1</Board2>
<Slot1> <-Elem2*
<Board0>1</Board0> <-Elem3*
<Board1>0</Board1>
<Board2>1</Board2>
</Chassis0>
<Chassis1>
<Fan1Present>0</Fan1Present>
<Fan2Present>1</Fan2Present>
<Fuse1>0</Fuse1>
<Fuse2>0</Fuse2>
<Slot0>
<Board0>1</Board0>
<Board1>0</Board1>
<Board2>1</Board2>
<Slot1>
<Board0>1</Board0>
<Board1>0</Board1>
<Board2>1</Board2>
</Chassis1>
</Rack>
*/
//File reads would be replaced with micro-controller queries
//to interrogate variable rack/chassis configurations
// * XML Element pointer
char line[100],rline[100];
int a,b;
FILE *fp1;
FILE *fp2;
CVIXMLStatus stat;
CVIXMLDocument doc;
CVIXMLElement rootElem,Elem1,Elem2,Elem3,Elem4;
//Build XML file
stat=CVIXMLNewDocument ("Rack", &doc);
stat=CVIXMLGetRootElement (doc, &rootElem);
//Get MF Header
for (a=0;a<2;a++)
{
//Fixed # Chassis Items
stat=CVIXMLNewElement (rootElem, -1, "Chassis", &Elem1);
stat=CVIXMLNewElement (Elem1, -1, "Fan1Present", &Elem2);
stat = CVIXMLSetElementValue (Elem2, "0");
stat=CVIXMLNewElement (Elem1, -1, "Fan2Present", &Elem2);
stat = CVIXMLSetElementValue (Elem2, "1");
//Variable # Chassis items read from file #1
//if items not present, don't write XML keys
fp1 = fopen("file1.txt","rt");
if (fp1 != NULL)
{
while (fgets(rline,50,fp1))
{
stat=CVIXMLNewElement (Elem1, -1, rline, &Elem2);
stat = CVIXMLSetElementValue (Elem2, "1");
}
fclose(fp1);
}
//Variable # Slot items read from file #2, (2) slots per chassis
//if slots not occupied, don't write XML keys
for (b=0;b<2;b++)
{
fp2 = fopen("file2.txt","rt");
if (fp2 != NULL)
{
Fmt(line,"%s<%s%d","Slot",b);
stat=CVIXMLNewElement (Elem2, -1, line, &Elem3);
while (fgets(rline,50,fp2))
{
stat=CVIXMLNewElement (Elem3, -1, rline, &Elem4);
stat = CVIXMLSetElementValue (Elem4, "0");
}
fclose(fp2);
}
}
}
CVIXMLDiscardElement(Elem1);
CVIXMLDiscardElement(Elem2);
CVIXMLDiscardElement(Elem3);
CVIXMLDiscardElement(Elem4);
CVIXMLDiscardElement(rootElem);
CVIXMLSaveDocument (doc, 0, "test.xml");
CVIXMLDiscardDocument(doc);
}
FILE1::
Fuse1
Fuse2
FILE2::
Board0
Board1
Board2
09-30-2011 01:47 PM
This is the output as viewed in IE:
09-30-2011 01:48 PM
I modd'ed the XML schema from the original post but the structure is the same...
-Chet
09-30-2011 01:53 PM
10-03-2011 10:55 AM
The reason you get the exception is because rline - the string you read from your file has invalid character (0x0A) and you cannot create XML tags with this character. You can remove this using the RemoveSurroundingWhiteSpace toolbox function. Also, I noticed that your code does not really map to the schema in your comments - you are using Elem2 instead of Elem1 as the parent to create the Slot elements. Here is the fixed code:
void CreateXML()
{
/* Desired XML Schema
<Rack> <-rootElem*
<Chassis0> <-Elem1*
<Fan1Present>0</Fan1Present>
<Fan2Present>1</Fan2Present>
<Fuse1>0</Fuse1>
<Fuse2>0</Fuse2>
<Slot0> <-Elem2*
<Board0>1</Board0> <-Elem3*
<Board1>0</Board1>
<Board2>1</Board2>
<Slot1> <-Elem2*
<Board0>1</Board0> <-Elem3*
<Board1>0</Board1>
<Board2>1</Board2>
</Chassis0>
<Chassis1>
<Fan1Present>0</Fan1Present>
<Fan2Present>1</Fan2Present>
<Fuse1>0</Fuse1>
<Fuse2>0</Fuse2>
<Slot0>
<Board0>1</Board0>
<Board1>0</Board1>
<Board2>1</Board2>
<Slot1>
<Board0>1</Board0>
<Board1>0</Board1>
<Board2>1</Board2>
</Chassis1>
</Rack>
*/
//File reads would be replaced with micro-controller queries
//to interrogate variable rack/chassis configurations
// * XML Element pointer
char line[100],rline[100];
int a,b;
FILE *fp1;
FILE *fp2;
CVIXMLStatus stat;
CVIXMLDocument doc;
CVIXMLElement rootElem,Elem1,Elem2,Elem3,Elem4;
//Build XML file
stat=CVIXMLNewDocument ("Rack", &doc);
stat=CVIXMLGetRootElement (doc, &rootElem);
//Get MF Header
for (a=0;a<2;a++)
{
//Fixed # Chassis Items
stat=CVIXMLNewElement (rootElem, -1, "Chassis", &Elem1);
stat=CVIXMLNewElement (Elem1, -1, "Fan1Present", &Elem2);
stat = CVIXMLSetElementValue (Elem2, "0");
CVIXMLDiscardElement(Elem2);
Elem2 = 0;
stat=CVIXMLNewElement (Elem1, -1, "Fan2Present", &Elem2);
stat = CVIXMLSetElementValue (Elem2, "1");
CVIXMLDiscardElement(Elem2);
Elem2 = 0;
//Variable # Chassis items read from file #1
//if items not present, don't write XML keys
fp1 = fopen("file1.txt","rt");
if (fp1 != NULL)
{
while (fgets(rline,50,fp1))
{
RemoveSurroundingWhiteSpace(rline);
stat=CVIXMLNewElement (Elem1, -1, rline, &Elem2);
stat = CVIXMLSetElementValue (Elem2, "1");
CVIXMLDiscardElement(Elem2);
Elem2 = 0;
}
fclose(fp1);
}
//Variable # Slot items read from file #2, (2) slots per chassis
//if slots not occupied, don't write XML keys
for (b=0;b<2;b++)
{
fp2 = fopen("file2.txt","rt");
if (fp2 != NULL)
{
Fmt(line,"%s<%s%d","Slot",b);
stat=CVIXMLNewElement (Elem1, -1, line, &Elem3);
while (fgets(rline,50,fp2))
{
RemoveSurroundingWhiteSpace(rline);
stat=CVIXMLNewElement (Elem3, -1, rline, &Elem4);
stat = CVIXMLSetElementValue (Elem4, "0");
CVIXMLDiscardElement(Elem4);
Elem4 = 0;
}
fclose(fp2);
CVIXMLDiscardElement(Elem3);
Elem3 = 0;
}
}
CVIXMLDiscardElement(Elem1);
Elem1 = 0;
}
if (Elem1)
CVIXMLDiscardElement(Elem1);
if (Elem2)
CVIXMLDiscardElement(Elem2);
if (Elem3)
CVIXMLDiscardElement(Elem3);
if (Elem4)
CVIXMLDiscardElement(Elem4);
if (rootElem)
CVIXMLDiscardElement(rootElem);
CVIXMLSaveDocument (doc, 0, "test.xml");
CVIXMLDiscardDocument(doc);
}
10-03-2011 12:05 PM
Mohan,
Thank you.
By luck, one of the lines in the first file did not throw an excemption, the one without the linefeed...
so I was looking at that as well.
Is there a document or link where one could learn the proper method of composing the XML file, in particular,
you disposed of the elements after each use. Would there be instances were you would not dispose of
them?
Thank you for a great solution!
-Chet:manvery-happy:
10-04-2011 09:17 AM
You should always dispose of the XML handles when your program does not need them any more - it is just like any other resource, for example, memory, file-handle, etc. A good resource that shows how to use the CVIXML functions is the samples/toolbox/xmlsample example program.