RAHUL
RAHUL

Reputation: 1

Fill a template file with data from XML

I have an XML file

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE labels SYSTEM "label.dtd">
   <labels _FORMAT ="BARCODE" _QUANTITY="1" _PRINTERNAME="P1">

        <label>
             <variable name= "PRTNUM">234243242</variable>
             <variable name= "QUANTY">004342</variable>
             <variable name= "PONUMB">844463541</variable>
             <variable name= "SERIAL">DZ12</variable>
             <variable name= "REV">234235</variable>
             <variable name= "UNITS">234235</variable>
        </label>

     </labels>

which i have parsed i.e the contain between <>...... tags eg. 004342 only 004342 data is read & other is neglected. Thus the whole parsed data i have saved into another file name parsed.txt which looks like

234243242
004342
844463541
DZ12
234235
234235

this parsed data i have to merge with the other file (barcode.dpl)

c0001

f260

L

D11

H30

R0000

C0040

1X1100000100010B300300003003

181100202900027Part No

181100202900097[PRTNUM]

1e5504002400030B

1X1100002300010L300003

191100202000030Quantity

191100202000080[QUANTY]

1e5504001500040B

1X1100001400010L300003

1X1100001400150L003090

191100202000170P.O.No

191100202000220[PONUMB]

1e5504001500180B

191100201200030Supplier

1e3304000700030B

1X1100000600010L300003

181100200300030Serial

181100200300090[SERIAL]

171100300900190Rev

171100300300190[REV]

171100300900240Units

171100300300240[UNITS]

1X1100000100180L003130

Q0001

E

the parsed data will put at the place of [PRTNUM], [QUANTY], [PONUMB] etc. & the file will look like....

c0001

f260

L

D11

H30

R0000

C0040

1X1100000100010B300300003003

181100202900027Part No

181100202900097234243242

1e5504002400030B

1X1100002300010L300003

191100202000030Quantity

191100202000080004342

1e5504001500040B

1X1100001400010L300003

1X1100001400150L003090

191100202000170P.O.No

191100202000220844463541

1e5504001500180B

191100201200030Supplier

1e3304000700030B

1X1100000600010L300003

181100200300030Serial

181100200300090DZ12

171100300900190Rev

171100300300190234235

171100300900240Units

171100300300240234235

1X1100000100180L003130

Q0001

E

so actually my problem is parsed data place at the position when it detects [....] from barcode file irrespective of the tag name given in xml & barcode file...if i put [QUANTY] at the position of [PRTNUM] it will place the same data 234243242 (which actually for [PRTNUM]). How to make it possible that my program will read the data inside [...] from barcode.txt file & then place the corresponding data from parsed file at that position.

my c code is...

#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<DIR.h>
#include<string.h>

int main()
{

  clrscr();

  int a[1];

  char cBuffer[50] = {0};

  char ch, cSkipdata;

  FILE* fPtr;

  FILE* fPparse;

  FILE* fPin;

  FILE* fPout;

  char* Ptr;




      getcwd(cBuffer, 100);
      printf("The current directory is %s\n\n",cBuffer);
      fPtr = fopen("sample.xml", "r");                    /* Open XML file*/
      fPparse = fopen("parse.txt","w");


      if(fPtr)
      {


    printf("The file is\n\n");
    scanf("%c",&a[1]);
                            // look for test between > and <
    cSkipdata=1;
    while ((ch = getc(fPtr)) != EOF)                     /* read character */
    {

           if(ch == '<')
              cSkipdata=1;

           if(!cSkipdata && ch != ' ')
           {

            putchar(ch);
             // fputc(ch ,stdout);
            fputc(ch, fPparse);
           }
                                 /* write character */
    if(ch == '>')

          cSkipdata=0;
   }





  fclose(fPtr);
  fclose(fPparse);

  }

  else

  {

    printf("file can not open\n");

  }

    fPin = fopen("barcode.txt", "r");                 /* Open DPL file*/
    fPout = fopen("final.txt", "w");                  /* Open the output final to save changea*/
    fPparse = fopen("parse.txt","r");

    scanf("%c",&a[1]);
    printf("\n\nfinal.txt is \n");
       cSkipdata = 0;
  while((ch = getc(fPin)) != EOF)
  {


        if(ch == '[')                                                   /* Skip the data if condition is true*/

        {


              int iLine=0;
             cSkipdata = 1;

        while ( (ch = getc(fPparse)) != EOF)            //f read a character
        {
                                  //if newline and we have output data break
             if((ch=='\n')  && (iLine>0) )

            break;                                       // end of line
                                //if not space output character

                if(ch > ' ')
                {
                                  // valid character output
                   iLine++;
                   putchar(ch);
                   fputc(ch, fPout);

                 }
           }

        }



        if(cSkipdata)
        {

         if(ch == ']')

            cSkipdata = 0;



        }


        else
        {

            putchar(ch);
            fputc(ch ,fPout);



        }


  }

           fclose(fPin);
           fclose(fPout);
           fclose(fPparse);







getch();
}

Upvotes: 0

Views: 212

Answers (1)

user2371524
user2371524

Reputation:

Trying to parse XML with some simple code is almost always a bad idea. Use a a library (libxml2) for that, see the libxml Tutorial, "Parsing the file".

Once you have your document, read the template file line by line, looking for bracket pairs, taking the substring between them as key for an XPath lookup on your xmlDoc, see "Using XPath to Retrieve Element Content".

Could look like this:

/* get element content by attribute selector */
xmlChar *labelContent(const char *name)
{
    /* xpath code here ... */
}

int main(void)
{
    /* [...] */

    char inbuf[1024];
    while (fgets(inbuf, 1024, fPin) > 0)
    {
        char *inc = inbuf;
        char *name = 0;
        xmlChar *val;

        while (*inc)
        {
            if (name)
            {
                if (*inc == ']')
                {
                    /* end found, replace with string terminator */
                    *inc = 0;

                    /* output value for label, increment name to skip '[' */
                    val = labelContent(++name);
                    fputs(val, fPout);
                    xmlFree(val);

                    /* leave template tag mode */
                    name = 0;
                }
            }
            else
            {
                if (*inc == '[')
                {
                    /* start of template tag */
                    name = inc;
                }
                else
                {
                    /* all other characters go directly to ouptut file */
                    fputc(*inc, fPout);
                }
            }
            ++inc;
        }

        /* no matching ']' found, output rest of line verbatim */
        if (name) fputs(name, fPout);
        name = 0;
    }

    /* [...] */
}

All in all, it will take considerably more effort than you thought ;) Code is just example, didn't try to compile.

edit: If you absolutely HAVE to parse the XML yourself, I just put something together that manages to parse your example file. It is still minimal, ignoring a lot of things possible in XML like escaping, quoting with single quotes, any entity sequences and so on. So something like this shouldn't be called an XML parser, but it might help you.

update: I now took the time to properly release this code, because it COULD be generally useful, fixing some small bugs on the way, so better refer to the new github repo "badxml".

Upvotes: 1

Related Questions