.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "XMLForm 3pm"
.TH XMLForm 3pm "2022-06-10" "perl v5.34.0" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
CGI::XMLForm \- Extension of CGI.pm which reads/generates formated XML.
.PP
NB: This is a subclass of CGI.pm, so can be used in it's place.
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 1
\& use CGI::XMLForm;
\&
\& my $cgi = new CGI::XMLForm;
\&
\& if ($cgi\->param) {
\& print $cgi\->header, $cgi\->pre($cgi\->escapeHTML($cgi\->toXML));
\& }
\& else {
\& open(FILE, "test.xml") or die "Can\*(Aqt open: $!";
\& my @queries = (\*(Aq/a\*(Aq, \*(Aq/a/b*\*(Aq, \*(Aq/a/b/c*\*(Aq, /a/d\*(Aq);
\& print $cgi\->header,
\& $cgi\->pre($cgi\->escapeHTML(
\& join "\en", $cgi\->readXML(*FILE, @queries)));
\& }
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
This module can either create form field values from \s-1XML\s0 based on \s-1XQL/XSL\s0 style
queries (full \s-1XQL\s0 is _not_ supported \- this module is designed for speed), or it
can create \s-1XML\s0 from form values. There are 2 key functions: toXML and readXML.
.SS "toXML"
.IX Subsection "toXML"
The module takes form fields given in a specialised format,
and outputs them to \s-1XML\s0 based on that format. The idea is that you
can create forms that define the resulting \s-1XML\s0 at the back end.
.PP
The format for the form elements is:
.PP
.Vb 1
\&
.Ve
.PP
which creates the following \s-1XML:\s0
.PP
.Vb 7
\&
\&
\&
\&
Entered Value
\&
\&
\&
.Ve
.PP
It's the user's responsibility to design appropriate forms to make
use of this module. Details of how come below...
.PP
Also supported are attribute form items, that allow creation
of element attributes. The syntax for this is:
.PP
.Vb 1
\&
.Ve
.PP
Which creates the following \s-1XML:\s0
.PP
.Vb 3
\&
\&
\&
.Ve
.PP
Also possible are relative paths. So the following form elements:
.PP
.Vb 4
\&
\&
\&
\&
.Ve
.PP
Will create the following \s-1XML:\s0
.PP
.Vb 9
\&
\&
\&
value1
\&
value2
\&
\&
\&
value3
\&
\&
.Ve
.SH "SYNTAX"
.IX Header "SYNTAX"
The following is a brief syntax guideline
.PP
Full paths start with a \*(L"/\*(R" :
.PP
.Vb 1
\& "/table/tr/td"
.Ve
.PP
Relative paths start with either \*(L"..\*(R" or just a tag name.
.PP
.Vb 2
\& "../tr/td"
\& "td"
.Ve
.PP
\&\fBRelative paths go at the level above the previous path, unless the previous
path was also a relative path, in which case it goes at the same level.\fR This
seems confusing at first (you might expect it to always go at the level above
the previous element), but it makes your form easier to design. Take the
following example: You have a timesheet (see the example supplied in the
archive) that has monday,tuesday,etc. Our form can look like this:
.PP
.Vb 4
\&
\&
\&
\& ...
.Ve
.PP
Rather than:
.PP
.Vb 5
\&
\&
\&
\&
\& ...
.Ve
.PP
If unsure I recommend using full paths, relative paths are great for repeating
groups of data, but weak for heavily structured data. Picture the following
paths:
.PP
.Vb 4
\& /timesheet/employee/name/forename
\& ../surname
\& title
\& ../department
.Ve
.PP
This actually creates the following \s-1XML:\s0
.PP
.Vb 10
\&
\&
\&
\& val1
\& val2
\& val3>
\&
\& val4
\&
\&
.Ve
.PP
Confusing eh? Far better to say:
.PP
.Vb 4
\& /timesheet/employee/name/forename
\& /timesheet/employee/name/surname
\& /timesheet/employee/name/title
\& /timesheet/employee/department
.Ve
.PP
Or alternatively, better still:
.PP
.Vb 5
\& /timesheet/employee/name (Make hidden and no value)
\& forename
\& surname
\& title
\& ../department
.Ve
.PP
Attributes go in square brackets. Attribute names are preceded with an \*(L"@\*(R",
and attribute values follow an \*(L"=\*(R" sign and are enclosed in quotes. Multiple
attributes are separated with \*(L" and \*(R".
.PP
.Vb 1
\& /table[@bgcolor="blue" and @width="100%"]/tr/td
.Ve
.PP
If setting an attribute, it follows after the tag that it is associated with,
after a \*(L"/\*(R" and it's name is preceded with an \*(L"@\*(R".
.PP
.Vb 1
\& /table/@bgcolor
.Ve
.SS "readXML"
.IX Subsection "readXML"
readXML takes either a file handle or text as the first parameter and a list of
queries following that. The \s-1XML\s0 is searched for the queries and it returns a
list of tuples that are the query and the match.
.PP
It's easier to demonstrate this with an example. Given the following \s-1XML:\s0
.PP
.Vb 11
\& Foo
\& Bar
\& Fred
\& Blogs
\&
\& Red
\& Barbara
\& Cartland
\&
\& Food
\&
.Ve
.PP
And the following queries:
.PP
.Vb 4
\& /a
\& /a/b*
\& c*
\& /a/d
.Ve
.PP
it returns the following result as a list:
.PP
.Vb 10
\& /a
\& Foo
\& /a/b
\& Bar
\& c
\& Fred
\& c
\& Blogs
\& /a/b
\& Red
\& c
\& Barbara
\& c
\& Cartland
\& /a/d
\& Food
.Ve
.PP
(\s-1NB:\s0 This is slightly incorrect \- for /a and /a/b it will return \*(L"Foo\en \*(R" and
\&\*(L"Bar\en \*(R" respectively).
.PP
The queries support relative paths like toXML (including parent paths), and
they also support wildcards using \*(L".*\*(R" or \*(L".*?\*(R" (preferably \*(L".*?\*(R" as it's
probably a better match). If a wildcard is specified the results will have the
actual value substituted with the wildcard. Wildcards are a bit experimental,
so be careful ;\-)
.SS "Caveats"
.IX Subsection "Caveats"
There are a few caveats to using this module:
.IP "\(bu" 4
Parameters must be on the form in the order they will appear in the \s-1XML.\s0
.IP "\(bu" 4
There is no support for multiple attribute setting (i.e. you can only
set one attribute for an element at a time).
.IP "\(bu" 4
You can't set an attribute \fBand\fR a value for that element, it's one or the
other.
.IP "\(bu" 4
You can use this module in place of \s-1CGI\s0.pm, since it's a subclass.
.IP "\(bu" 4
There are bound to be lots of bugs! Although it's in production use
right now \- just watch \s-1CPAN\s0 for regular updates.
.SH "AUTHOR"
.IX Header "AUTHOR"
Matt Sergeant msergeant@ndirect.co.uk, sergeant@geocities.com
.PP
Based on an original concept, and discussions with, Jonathan Eisenzopf.
Thanks to the Perl-XML mailing list for suggesting the \s-1XSL\s0 syntax.
.PP
Special thanks to Francois Belanger (francois@sitepak.com) for
his mentoring and help with the syntax design.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\s-1\fBCGI\s0\fR\|(1), \s-1CGI::XML\s0