LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

XML Nested Element HELP

Solved!
Go to solution

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>

0 Kudos
Message 1 of 9
(4,495 Views)

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

Regards,

Kyle M.
Applications Engineering
National Instruments
0 Kudos
Message 2 of 9
(4,471 Views)

 

Thank you for looking into this:Smiley Very Happy

 

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

0 Kudos
Message 3 of 9
(4,467 Views)

This is the output as viewed in IE:

 

  <?xml version="1.0" ?>
- <Rack>
- <Chassis>
  <Fan1Present>0</Fan1Present>
  <Fan2Present>1</Fan2Present>
- <Fuse2>
  1
- <Slot0>
  <Board2>0</Board2>
  </Slot0>
- <Slot1>
  <Board2>0</Board2>
  </Slot1>
  </Fuse2>
  </Chassis>
- <Chassis>
  <Fan1Present>0</Fan1Present>
  <Fan2Present>1</Fan2Present>
- <Fuse2>
  1
- <Slot0>
  <Board2>0</Board2>
  </Slot0>
- <Slot1>
  <Board2>0</Board2>
  </Slot1>
  </Fuse2>
  </Chassis>
  </Rack>
0 Kudos
Message 4 of 9
(4,466 Views)

 

I modd'ed the XML schema from the original post but the structure is the same...

 

-Chet

0 Kudos
Message 5 of 9
(4,465 Views)

 

ChetK -> JolleyRogers (?? 2 profiles)

 

Spoiler
alias

 

0 Kudos
Message 6 of 9
(4,462 Views)
Solution
Accepted by topic author ChetK

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);
 

}

Message 7 of 9
(4,432 Views)

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:

0 Kudos
Message 8 of 9
(4,425 Views)

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.

0 Kudos
Message 9 of 9
(4,415 Views)