[ic] Nested tags SOLVED!! + simple xml parsing tag
Marc Brevoort
interchange-users@icdevgroup.org
Fri Feb 21 05:10:01 2003
On Thu, 2003-02-20 at 17:55, Kevin Walsh wrote:
> > I suppose the correct evaluation order could be forced
> > with something like
> >
> > [parsexml xml="[posttourl url=".....]"]
> >
> Add the following to your parsexml UserTag definition:
>
> UserTag parsexml Interpolate 1
>
> That would cause the body text to be interpolated for other tags
> before passing the resulting text to your UserTag.
At last, attempt number 228 gave me the desired result. A big THANK YOU
is in place here. Without the list, it'd probably have cost at least
double the effort, so here's a little something in return (with
whitespace, this time ;) )
Regards,
Marc Brevoort
# ---------- snip snip ----------------------------
Usertag parsexml hasEndTag
Usertag parsexml Interpolate 1
Usertag parsexml Routine <<EOR
#######################################################
# This usertag takes a block of XML and parses it.
# The found variables will be stored in $CGI.
# Return value of the tag is the list of parsed
# variables.
# Currently, the tree structure of the XML document
# is not preserved.
######################################################
sub {
##############################################
# This part sets up the XML parser for
# processing the result of the POST operation
##############################################
# This part only declares/initalizes some stuff
# for them to be in scope to the subs defined
# next
my ($xml)=@_;
require XML::Parser;
my @field=();
my $tag="";
my $result="";
sub cleanupxml {
##################################################
# This sub attempts to remove some non-xml trash
# from the returned result of the post operation
# to prevent confusing the XML parser.
# Also, it wraps the xml in tags <XMLDOC_WRAPPER>
# to make the parser tolerate empty xml.
##################################################
my ($xmltoclean)=@_;
my $cleanedxml="";
my $returnxml="";
my $start="";
my $line="";
my $x=substr($xmltoclean,1,6);
if (index($xmltoclean,"\<\?xml")<0) {
$cleanedxml="<\?xml version=\"1.0\" encoding=\"UTF-8\"\?\>"
."\n"
# ."\<temp\>".$x."\<\/temp\>" # for debugging
.$xmltoclean;
} else {
$cleanedxml=substr($xmltoclean,index($xmltoclean,"\<\?xml"));
}
my @xmllines=split("\n",$cleanedxml);
foreach $line (@xmllines) {
next if (($line eq "")||($line eq "\n")||($line eq "\r")||($line eq
"\s"));
if ($start ne "") {
$returnxml.=$line."\n";
next;
}
next if lc(substr($line,0,5)) ne "\<\?xml";
$returnxml.=$line."\n\<XMLDOC_WRAPPER\>\n";
$start="x";
}
if ($returnxml eq "") {
return $returnxml
."\<\?xml version=\"1.0\"
encoding=\"UTF\-8\"?>\n\<XMLDOC_WRAPPER\>\<\/XMLDOC_WRAPPER\>";
}
return $returnxml."\<\/XMLDOC_WRAPPER\>";
}
sub Start_Handler {
# Called when a xml tag start has been found.
my $p=shift;
my $el=shift;
$tag=$el;
while (my $key=shift) {
my $val=shift;
}
}
sub End_Handler {
# Called when a xml tag is closed,
# we do not use it for anything much.
my $p=shift;
my $el=shift;
}
sub Default_Handler {
# Called when content of a xml tag has been found.
my $p=shift;
my $el=shift;
if (($el eq "")||($tag eq "")) {
return;
}
if ($tag eq "XMLDOC_WRAPPER") {
return;
}
$CGI->{$tag}=$el;
$result.=$tag."=".$el."\n";
push @field,$tag;$tag="";
}
#####################################
# Tag's executable code starts here
#####################################
my $parser=new XML::Parser(ErrorContext=>2);
$parser->setHandlers(
Start=>\&Start_Handler,
End =>\&End_Handler,
Default=>\&Default_Handler
);
# $result.="--cleanup--<br>\n"; # for debugging
my $cleanxml=cleanupxml($xml);
# return $cleanxml; # Preliminary exit for debugging purposes
# $result.="cleanxml=<br>\n".$cleanxml."<br>\n"; # for debugging
my $parseresult=$parser->parse($cleanxml);
my $fieldname="";
# $result.=substr($cleanxml,1,8); # for debugging
foreach $fieldname (@field) {
next if $fieldname eq "";
next if $fieldname eq "XMLDOC_WRAPPER";
$result.=$fieldname.'='.$CGI->{$fieldname}."\n";
}
return $result;
}
EOR
####
--
e-mail: marc.brevoort@armazemdedados.com
web: http://www.armazemdedados.com
Armazem de Dados, Informatica, Lda
Dep. Desenvolvimento
Tel. +351 21 910 83 10 / Fax. +351- 21 910 83 19