Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

XML to CGI form

by BastardOperator (Monk)
on Nov 03, 2000 at 19:50 UTC ( [id://39836]=perlquestion: print w/replies, xml ) Need Help??

BastardOperator has asked for the wisdom of the Perl Monks concerning the following question:

After considering the responses given to a previous post, expect users to program of define a simple definition language?, I decided that XML was probably the best solution that I could hope for. So, I've been hacking around with some XML trying to figure out how I'm going to do this. Here's my question:

My intent was to have the user use XML to basically describe a cgi form (this would also need to describe the database structure) to take input with (although, it's possible that the user could want fields that wouldn't be displayed but have some type of processing occuring, anyway...). As I began to try to define how this would work (with c-era's help), I started to realize that, for as customizable as I want this, the user will have to get pretty darned verbose. The definition started to look more like the user was actually writing the html form, rather than just describing bits and pieces (although with some other key tags in there that I'd need to use, flags and the like). So, how should I do this? Is there a way to allow them to use XML to describe this (I need the data to be structured) and have it create the form without me having to parse it and figure out what they're doing?

I've thought of things like XSL, but that wouldn't really do the trick because then _I'd_ be defining the look of the form, plus it still seems too young. I looked around CPAN, Matt Seargant has a CGI::XMLform that does just the opposite of what I want to do, and he mentions "coming later will be a small module that uses my XML::DTDParser to create all the form elements given a DTD. ", but nothing so far that I can find.

I'm determined to do this right the first time, so I'd love it if someone could give me some input on this or point me to a module or a better way....

Thank you!

Replies are listed 'Best First'.
Re: XML to CGI form
by clemburg (Curate) on Nov 03, 2000 at 20:32 UTC

    You will want to have a look at Chapter 17, Template Driven Code Generation, in the "Advanced Perl Programming" book. This uses a C like language to specify object models to generate C++ headers and SQL statements.

    The classical reference for this type of stuff is of course: Little Languages. In: More Programming Pearls: Confessions of a Coder. John Bentley. Association for Computing Machinery, 1988. (BTW, if anyone out there has a copy of this book that he wants to sell, I would really, really like to buy it!)

    Another really easy syntax to set things like this up would be a LISP like (prefix) syntax (e.g., like Excel functions do it). You can easily parse this stuff and implement it by functions that you call from a central dispatcher.

    As for verbosity, it seems that all XML based stuff is incredibly verbose, so I doubt that this is such a good choice. Besides that, people who can write XML will be able to handle a CGI form, too. You will need a syntax simpler than that, IMHO. As mentioned above, I really like this Excel function like syntax - it is easy to implement, and users have got used to it.

    Christian Lemburg
    Brainbench MVP for Perl
    http://www.brainbench.com

RE: XML to CGI form
by mirod (Canon) on Nov 03, 2000 at 20:56 UTC

    Darn! I was just trying to do that!

    You might remember one of my pet projects, a Module Reviews (again!)

    So I was just trying to write a simple CGI that would do this, and I came up with this simple way to write a template to generate the form:

    <conf> <category id="usage" html="select" multiple="multiple"> <name>Usage</usage> <option id="read">Read Docs</option> <option id="tested">Tested</option> <option id="rejected">Rejected</option> <option id="used">Used</> <option id="used_a_lot">Used a lot</option> </category> <category id="quality" html="radio" type="number" range="0-5"> <name>Quality</name> </category> <category id="documentation" html="radio" type="number" range="0-5"> <nameDocumentaion></name> </category> <category id="support" html="radio" type="number" range="0-5" na="ye +s"> <name>Support</name> </category> </conf>

    Now I plan to use this config file to both generate the input form and then to drive the generation of the XML created when the form is used.

    Does this makes sense? And is this close to what you want to do?

    I'll have the code later, sorry, you just caught me in the act of writing it ;--(

      Yes, this is very close to what I want to do. Although data for multiple selects and the like could potentially be pulled from database tables. The big question is, how will you translate that to html? I'd like to allow them to specify a font or whatever, but in doing that it gets so close to being the actual html form, that I may as well have them write it in html :). Will you parse it yourself and translate? I'd like to know if there is a way to do that without parsing it completely yourself.

      Just for the sake of filling up vroom's database :), let me show you what I have so far (P.S. this describes a form, but it also tries to describe a table structure, both of which refer to adding an entry which is a computer system). This was done with the intent of parsing it myself to produce appropriate html, but again, if there's a way that I could rewrite/retag everything and use some module to produce the output, I'd love that.
      <?xml version="1.0" standalone="yes"?> <!-- Everyone gets an id for free, you must have a unique "subject" ro +w!!! --> <!-- i.e. for every addition to a type, an id will be assigned --> <!-- i.e. everything must have a row named subject (VARCHAR(128) max) +--> <!-- which will contain the hostname or whatever you like, but it --> <!-- _must_ be named "subject" --> <!-- Stuff to think about --> <!-- <macro type="sql">SELECT * from foo</macro> --> <!-- <macro type="perl">sub { print 4 * 50 }</macro> --> <!-- select id,subject from (whatever) where something="stuff" --> <!-- <target>id:subect:something="stuff"</target> ? --> <!-- <name>file</name><datatype>blob</datatype><style>file_upload</sty +le> --> <!-- ********** START SYSTEM DEFINITION ********** --> <form> <name>System</name> <post_notes_to>1</post_notes_to> <email_notes>1</email_notes> <row> <element> <label>Hostname</label> <name>subject</name> <required>1</required> <validchars>[\w\.-_]+</validchars> <datatype>varchar</datatype> <size>25</size> </element> </row> <row> <element> <label>Vendor/Model</label> <name>sysdesc</name> <required>1</required> <validchars>[\w\.-_]+</validchars> <datatype>varchar</datatype> <size>64</size> <default>Sun UE6500</default> <instructions>(i.e. Sun UE6500)</instructions> </element> </row> <row> <element> <label>Serial#</label> <name>serialnum</name> <required>0</required> <validchars>[\w\.-_:]+</validchars> <datatype>varchar</datatype> <size>32</size> </element> </row> <row> <element> <label>Maint Contract</label> <name>maint</name> <required>0</required> <datatype>varchar</datatype> <style>pulldown</style> <title>Select Contract...</title> <info_from>Maintenance</info_from> <target>id:subject</target> </element> </row> <row> <element> <label>Mac Address</label> <name>mac</name> <required>0</required> <validchars>[\w:]+</validchars> <datatype>varchar</datatype> <size>32</size> </element> </row> <row> <element> <label>OS Level</label> <name>oslevel</name> <required>0</required> <validchars>[\w\.]+</validchars> <datatype>varchar</datatype> <size>32</size> <default>SunOS 5.8</default> </element> </row> <row> <element> <label>IP Address</label> <name>ipaddr1</name> <required>0</required> <validchars>[\d/:\.]+</validchars> <datatype>varchar</datatype> <size>32</size> </element> </row> <row> <element> <label>Contacts</label> <name>icontacts</name> <required>0</required> <datatype>varchar</datatype> <style>multiple</style> <size>3</size> <title>==Internal Contacts==</title> <info_from>Internal Contacts</info_from> <target>id:subject</target> </element> <element> <name>vcontacts</name> <required>0</required> <datatype>varchar</datatype> <style>multiple</style> <size>3</size> <title>==Vendor Contacts==</title> <info_from>Vendor Contacts</info_from> <target>id:subject</target> </element> </row> <row> <element> <label>Description</label> <name>description</name> <required>0</required> <datatype>text</datatype> <style>textarea</style> <size>45w:10h</size> </element> </row> <row> <element> <label>Last Modified</label> <name>date</name> <required>0</required> <datatype>date</datatype> </element> </row> </form>
RE: XML to CGI form
by little (Curate) on Nov 03, 2000 at 20:01 UTC
    what about XML::Template ?
    Have a nice day
    All decision is left to your taste
Re: XML to CGI form
by mirod (Canon) on Nov 03, 2000 at 21:41 UTC

    I'll show you the code as soon as it's written! I have just one comment on the format you're using: consideringyou are doing really strict typing of the data, you might want to have a look at the W3C's XML Schemas, which (supposedly, I never actually read the spec) cover that feature quite well.

    As for parsing the data I'll use as usual XML::Twig to generate the form, and probably a combo of CGI::XMLform to get the data and XML::Twig to create the initial data for a module and to update it's record from the CGI, as it makes it pretty easy to update just a record with a given id (but of course I am partial to XML::Twig, especially as I can always fix it if there is any problem ;--)

    More on that later...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://39836]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-19 22:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found