I find myself feeling a little guilty as I write this, because I must sing a refrain that is all too familiar in a lot of my posts to the SOAP::Lite newsgroup, but building complex types in SOAP::Lite is a little challenging - certainly more challenging that your typical SOAP toolkit. However, this will hopefully be improved when SOAP::Lite v0.65 is released. So bare with me. In the meantime, if you want to build an array that other toolkits will parse, try a variant on the following code...
return SOAP::Data
->name("CallDetails" => \SOAP::Data->value(
SOAP::Data->name("elem1" => 'foo'),
SOAP::Data->name("elem2" => 'baz'),
SOAP::Data->name("someArray" =>
\SOAP::Data->value(SOAP::Data->name("someArrayItem" => @array)
->type("SomeObject"))
)->type("ArrayOf_SomeObject")
))->type("SomeObject");
}
I wrote a subroutine myself which does the above thing..It works just fine for me. I'd be glad to know if anyone notices any bugs. Here it is:
#########################################################################################
# Soapify
#
# Description:
# Given an arrayref (infinite depth), constructs a valid SOAP Object
#
# Parameters:
# $args: Arrayref
#
# Format of the arrayref:
# [xml_element_name, value, attributes]
# xml_element_name must be a scalar, value could be a scalar or another arrayref of the same format and
# attributes must be a hashref. xml_element_name and attributes are optional.
#
# Examples:
# 1. ["ElemName1", "ElemValue1", { "xmlns" => "http://blah/blah"}]
# 2. ["ElemName2", [
# ["NameAtLevel1", "ValueAtLevel1", {}],
# ], {"attrname" => "attrvalue"}]
# 3. [
# ["name", "value"]
# ]
#
# Return Value:
# SOAP object
#########################################################################################
sub Soapify {
my ($args) = (@_);
confess "The argument must be an rrayref!" if (ref($args) !~ /ARRAY/ );
my @namevaluearray = @$args;
my $soapobject = new SOAP::Data;
if (defined ($namevaluearray[0]) && ref($namevaluearray[0]) !~ /ARRAY/) {
#------------------name------------------------#
$soapobject->name($namevaluearray[0]);
#------------------value-----------------------#
if (defined $namevaluearray[1] && !ref($namevaluearray[1])) {
$soapobject->value($namevaluearray[1]);
}
elsif (ref($namevaluearray[1]) =~ /ARRAY/) {
my $soapvalue = Soapify($namevaluearray[1]);
my @pass = (ref($soapvalue) =~ /ARRAY/) ? @$soapvalue : ($soapvalue);
$soapobject->value(\SOAP::Data->value(@pass));
}
#-------------------attribute------------------#
my $attr = $namevaluearray[2];
if (ref($attr) =~ /HASH/) {
$soapobject->attr($attr);
}
}
elsif (ref($namevaluearray[0]) =~ /ARRAY/) {
my @valuesarray;
foreach my $element (@namevaluearray) {
my $reftoelement = (ref($element) =~ /ARRAY/) ? $element : [$element];
push(@valuesarray, Soapify($reftoelement));
}
return [@valuesarray];
}
return $soapobject;
}
Posted by: Sandeep Satavlekar | November 10, 2006 at 02:04 AM
ohh god! the entire indentation is lost. But I hope it'd still be straightforward to understand.
Rgds,
Sandeep Satavlekar
Posted by: Sandeep Satavlekar | November 10, 2006 at 02:06 AM