I wanted to build an awesome place for people to discuss module specific issues, but I don't have any more time for this, and there are much better places to discuss Perl-related issues. I'd recommend asking your question on Stack Overflow or on Perl Monks.
If you are looking for a Perl tutorial or Perl-related news, I hope these links will serve you well.
Posted on 2010-06-05 08:08:34.75652-07 by askucins
More parts in the Header - how handle that case?

Hi, I have a problem with a wsdl which contains two elements in the Header:
[...] <soap:operation soapAction=""/> <input> <soap:body parts="processRecords" use="literal"/> <soap:header message="tns:NACSB_processRecords" part="NAQO" use="literal"/> <soap:header message="tns:NACSB_processRecords" part="JobHeader" use="literal"/> </input> [..]

When i'm using the wsdl2perl from 2.00.10 it even doesn't create the second part in the interface:
header => { 'use' => 'literal', namespace => 'http://schemas.xmlsoap.org/wsdl/soap/', encodingStyle => '', parts => [qw( MyElements::NAQO )], },

and adding the JobHeader one to the 'parts' list doesn't help. It's weird since the POD of that interface actually shows something like:
$interface->processRecords({},{MyTypes::nAQO},{MyTypes::jobHeader})

but runnig that ends with an error (from the server), that the required JobHeader element is missing.
So I went and checked the developer's version: SOAP-WSDL-2.00.99_3
There is only a bit better. In the interface both parts are generated:
header => { 'use' => 'literal', namespace => 'http://schemas.xmlsoap.org/wsdl/soap/', encodingStyle => '', parts => [qw( MyElements::NAQO MyElements::JobHeader )], },

but later I'm getting the same error (missing JobHeader element) from the server.
So I tried to dig it a bit deeper, and realized (if i'm correct) that this is actually per design - I mean that only first element from the header is sent. I tried to change the code in SOAP/WSDL/Client/Base.pm ('call' function) and SOAP/WSDL/Serializer/XSD.pm ('serialize_header' function) and it seems it works now (all I did was to rewrite those two functions to mimic what is done for 'body' part.
Now I'm calling it in this way (wrapping in the [])
$interface->processRecords({},[{MyTypes::nAQO},{MyTypes::jobHeader}])

But since i'm definitely not very experienced in that stuff I would like to know what are yours ideas in that subject, I mean handling more elements in the header. Are there any handy examples already contained in the documentation, or maybe you have some real use cases?

Thanks,
Adam

(this is the change I did - all I needed was 'to make it work' so I guess it could be done better in general case:

a) SOAP/WSDL/Client/Base.pm SOAP-WSDL-2.00.99_3 in 'call' function
--- Base.pm.orig 2010-06-04 22:53:17.000000000 +0200 +++ Base.pm 2010-06-05 14:55:20.000000000 +0200 @@ -33,12 +33,27 @@ # if we have a header if (%{ $method->{ header } }) { - # treat non object special - as above, but only for one + # treat non object special - as above, but only for one + # <askuci> - an attempt to handle multi-parts headers if (not blessed $header) { - my $class = $method->{ header }->{ parts }->[0]; - eval "require $class" || die $@; ## no critic (ProhibitStringyEval) - $header = $class->new($header); + $header = {} if not defined $header; + $header = ref $header eq 'ARRAY' ? $header : [ $header ]; + my @header_from = @{ $header }; # make a copy + + my @part_from = (); + foreach my $class (@{ $method->{ header }->{ parts } }) { + my $part = (shift(@header_from) || {}); + if (blessed $part) { + push @part_from, $part; + } + else { + eval "require $class" || die $@; ## no critic (ProhibitStringyEval) + push @part_from, $class->new($part); + } + } + $header = $#part_from ? \@part_from : $part_from[0]; } + # </askuci> } return $self->SUPER::call($method, $body, $header); }

b) SOAP/WSDL/Serializer/XSD.pm SOAP-WSDL-2.00.99_3 in 'serialize_header' function
--- XSD.pm.orig 2010-03-28 12:46:00.000000000 +0200 +++ XSD.pm 2010-06-05 15:59:37.000000000 +0200 @@ -61,7 +61,11 @@ return q{} if not $data; return join ( q{}, "<$opt->{ namespace }->{ $SOAP_NS }\:Header>", - blessed $data ? $data->serialize_qualified : (), + # <askuci> To serialize multi-parts headers + ref $data eq 'ARRAY' + ? join q{}, map { blessed $_ ? $_->serialize_qualified() : () } @ { $data } + : blessed $data ? $data->serialize_qualified : (), + # </askuci> "</$opt->{ namespace }->{ $SOAP_NS }\:Header>", ); }
Direct Responses: Write a response