We help IT Professionals succeed at work.

parse a template file

samantha
samantha asked
on
373 Views
Last Modified: 2010-04-02
Hi,

This is what I want to achieve:

I have a text file as following:
=====================================
<html>
<body>
  Name:<$MY_TAG FIELD=name>
  TEL :<$MY_TAG FIELD=tel>
</body>
</html>
=====================================
I want to write a c program that read in this template file and replace <$MY_TAG ??????> with the data I retrieved from a database. And then prints out this file.

Can someone please tell me what's the good algorithm to use? Should I read this file into memory first and processes it from there.
Or is there any third-party C library that can help me do this?

Thanks in advance.

Comment
Watch Question

Commented:
Hi samantha,

I do not feel this problem as that of a parsing problem .May be the reverse and correct logic of your problem is to read out an array of name and tel pairs and generate the an output in the form of template

<html>
<body>
  Name:<$MY_TAG FIELD=name>
  TEL :<$MY_TAG FIELD=tel>
</body>
</html>

So you do it this way,
Read each record from the database and
write a code genrerator(so called) which will take in ( name1,telno1) and print the result in the form of

<html>
<body>
  Name:<$MY_TAG FIELD=name1>
  TEL :<$MY_TAG FIELD=tel1>
</body>
</html>

This you acheive simple by a series of printfs.
printf("<html> \n <body> \n   Name:<$MY_TAG FIELD=");
printf("%s",name1);
printf(>TEL :<$MY_TAG FIELD=");
printf("%s",tel1);
printf("> \n </body> \n</html> ");

Author

Commented:
Hi ufolk123,

Thanks for the answer. But that's not what I want. Maybe I didn't state the problem clearly. This is actually a CGI program.

Let's call this program test.c. And the template file template.txt:
=============================
<html>
<body>
  Name:<$MY_TAG FIELD=name>
  TEL :<$MY_TAG FIELD=phone>
</body>
</html>
=============================

And a database table like this:
==============================
ID       NAME        PHONE
01       Samantha    (111)111-1111
02       ufolk123    (222)222-2222
......
==============================

The program is invoked like this:

http://xx.com/test.exe?id=02&template= template.txt

This program then retrieves the Record 02 from the database and use the "template.txt" to generate the following result page:
=============================
<html>
<body>
  Name:ufolk123
  TEL :(222)222-2222
</body>
</html>
=============================

I don't want to hard code this file using printf() beacuse everytime you want to change the layout, you have to do it inside the code and recompile the program. With this template file, users of "test.exe" can always provide their own "template.txt".

Thanks,

Hmmm. Looks like a problem better suited to XML.

Commented:
I would use a kind of final state machine that will parse the input file.
I would read the input file char by char and look first, for a '<' then I 'd look of a '$', 'M', 'Y','_' etc....untill i get the string '<$MY_TAG FIELD=' now, I know that the following string (up to the next '>') is the requiered field. After knowing wat field it is, just use the database's interface as you normaly do.
BTW, while you look for the first '<' just read the char and output it if it's not '<'. Your code should look something like this:
----------------------------
char ch,needed_ch,temp_array[100];
int state=0; /* state will record the state of the FSM (i.e., how many chars we've read so far that match the string we're looking for.*/
FILE* in_file,out_file; /* assuming files are open...*/

while ((ch=getc(infile))!=EOF)
{
  switch (state)
  {
     case (0):
       needed_ch='<';
       break;
     case (1):
       needed_ch='$';
       break;
     case (2):
       needed_ch='M';
       break;
/* continue with cases */
  }
  if (ch==needed_ch) /* did we get what we wanted ? */
  {
     temp_array[state]=ch;
     temp_array[state+1]='\0'; /* terminating NULL*/
     if (state==MAX_NUM_OF_STATES) /* which is the length of '<$MY_TAG FIELD' */
     {
        /* do data base stuff here and output the correct field's value */
     }
  }  else /* didn't get what we wanted.*/
     {
       putc (ch,out_file); /* just output the given char*/
       state=0; /* start over*/
     }
}

----------------------------
Please note that this code wasn't tested and compiled so it may have some erros but it should give you a clear idea.

Arnon David.
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
Thanks a lot, guys.

arnond & alexo, both your answers are excellent.  I wish they had a way to let me split the points to both of you.

Since alexo has locked it, I am giving the points to him.  Sorry, arnond. But if you can tell me how I can give you the points, I will also give 100 points.

Thanks again.  

Commented:
If you want to spend an extra 100 points, just post another (empty) question titled something like "points for arnond" and I'll "answer" it and you'll accept.
But, do that only if you want to.

Thanks,
Arnon David.

Commented:
If you don't have enough points, I can give Arnon 100+A of my own (I got some spare since I rarely ask questions).  Post a comment here in case you like the idea.

Commented:
it's ok, she already posted one.

thanks anyway,
Arnon David.
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.