After thinking out loud in my last post, here is some new code that
illustrates how to do generic replacement processing with on-the-fly
formatting... It is a quick perl script but is basically the guts for a
my:sub XMLSubs-type function...
#! /bin/perl
my $body = << "EOF";
<fmt>PRICE:%.2f,AGE:%3d,STATE:%uc2</fmt>
Price \$__PRICE__ - You must be __AGE__ years old to buy in __STATE__.
EOF
my %hash = (
price => 12,
age => 18,
state => 'va',
);
my %fmt = (); # for format view
## extract format (if any) - what's left becomes template string
$body =~ s/<fmt>(.*?)<\/fmt>//i;
$fmt = $1;
## scoop-up formats into a convenient hash
foreach (split(/,/, $fmt)) {
my ($key, $val) = split(/:/, $_);
$fmt{uc(eatwhite($key))} = eatwhite($val);
}
## render hash using template string and format hash
render($body, \%hash, \%fmt);
sub render { ## process template using data in hash and formatting info
my $tmpl = shift;
my $hash = shift;
my $fmt = shift;
foreach (keys %$hash) {
my $key = uc($_);
if ($$fmt{$key} ne undef) {
my $fmt = $$fmt{$key};
if ($fmt =~ /^%uc/i) { # to-uppercase
$fmt =~ s/[^0-9]//g;
$$hash{$_} = uc(substr($$hash{$_}, 0, $fmt ||
length($$hash{$_})));
}
elsif ($fmt =~ /^%lc/i) { # to-lowercase
$fmt =~ s/[^0-9]//g;
$$hash{$_} = lc(substr($$hash{$_}, 0, $fmt ||
length($$hash{$_})));
}
else { # picture
$$hash{$_} = sprintf($fmt, $$hash{$_});
}
}
$tmpl =~ s/__${key}__/$$hash{$_}/gie;
}
print "$tmpl\n";
}
## convenience function
sub eatwhite { $_[0] =~ s/^\s*(.*?)\s*$/$1/; return $_[0] };
__END__
This script simulates the guts of the following XMLSubs scenario:
<my:sub ...>
<fmt>PRICE:%.2f,AGE:%3d,STATE:%uc2</fmt>
Price \$__PRICE__ - You must be __AGE__ years old to buy in __STATE__.
</my:sub>
The format info is scooped-up into the %fmt hash and each item in the hash is
processed according to its format data, if available. Otherwise its just
directly replaced. Two pseudo formats are also available: %lcN and %ucN
(where N is a positive integer representing the max chars to return -- N can
also be left off in which case the entire string will be processed and
returned).
This type of processing would simplify _many_ chores-- for example, consider
this hypothetical example in which "my:sub" retrieves one or more rows of
data and then renders them according to the body info:
<table>
<my:sub search="search_string" >
<fmt>COST:%.2f,PRICE:%.2f</fmt>
<tr><td>__PART__</td><td>__NAME__</td><td>__DESCR__</td><td>__COST__</td><td>__PRICE__</td></tr>
</my:sub>
</table>
And that would be pretty much the WHOLE html file. All of the nasty bits are
hidden away in the 'my:sub' functionality.
Another interesting way to process vars, and more in keeping with the JSP
Taglib stuff you mentioned (I did some reading today ;) would be a script
similar to this:
#! /bin/perl
## script to test matching parameters
my $str1 = "NAME: John AGE: 40 SEX: M";
my $str2 = "NAME: Wendy AGE: 42 SEX: F";
my $str3 = "NAME: Scott SSN: 36 SEX: M";
my $str4 = "NAME: Beck AGE: 30 SEX: F";
my @fields = qw(name age sex);
my $pat = 'NAME: (.*?) AGE: (\d+) SEX: (.*)$';
print "STR: '$str'\n";
print "PAT: /$pat/\n";
print "\n";
foreach ($str1, $str2, $str3, $str4) {
my $hash = extractData($_, $pat, \@fields);
if ($hash eq undef) { print "WARNING - Encountered bad data\n" }
else { foreach (keys %$hash) { print "KEY = $_, VAL = $$hash{$_}\n" }}
print "-"x72, "\n";
}
sub extractData {
my $str = shift;
my $pat = shift;
my $fields = shift;
my $count = 0;
my %h = ();
$str =~ /$pat/;
while (${++$count} ne undef) { $h{$$fields[$count-1]} = ${$count} }
return \%h if ($count-1 == scalar @$fields); # correct field count
return undef; # bad field count
}
__END__
This script simulates the $1, $2, $3 functionality of pattern matching but in
such a way that any number of pattern-tokens can be matched and returned
without knowing the exact number beforehand-- this way a generic pattern
processor can be used to apply a pattern against a string and return the
matched data. This script does not use the exact %1, %2, %3 syntax that
Taglibs calls for, but that's a minor issue and could be worked in. The
harder part was coming up with a way to work iterate the $1, $2.. vars which
don't like to be iterated. This code snippet was not actually originally for
an ASP script, but when Josh mentioned that bit about the JSP Taglibs and I
read up on it, this snippet immediately came to mind. I can't imagine that it
would be that hard to adapt to the concept.
As always, I hope someone might find some of this stuff useful, informative,
or at least interesting ;)
John Whitten
[EMAIL PROTECTED]
Wizard.Org, Inc.
--
--------------------------------------------------------------------------------
Check out http://www.Wizard.Org for great deals on Electronic Parts
*NEW* Computer Parts & Accessories - Drives - LCD - Systems - Linux
--------------------------------------------------------------------------------
** Affordable Online Store w/Merchant Card Processing & Paypal **
Write to us: [EMAIL PROTECTED] -- Get your Store Online Today!
--------------------------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]