Search code examples
perlweb-serviceswcfsoapsoaplite

Append an element to an already existing SOAP::Data complex type


I'm very new to SOAP, PERL and pretty much everything else I've been asked to do so I'm hoping someone can point me in the right direction.

I've implemented a simple WCF solution and I've written a PERL client which passes a "complex data structure" to the solution using SOAP::lite and SOAP::Data. All this works very well so far, WCF solution see's the array as an array and I'm able to iterate through the array on the server side just fine.

However, I'm having an issue trying to append a data element to the array on the PERL side. I have the following code, which builds the array I need, but I need to append a few lines to the array later on in the code and I can't figure out how to that.

# build array of values
my $data= SOAP::Data->new
(name => 'array', value => 
   [
     SOAP::Data->new(name => 'elem:string', value => 'firststring'),
     SOAP::Data->new(name => 'elem:string', value => 'secondstring'),
     SOAP::Data->new(name => 'elem:string', value => 'thridstring')
   ]
) 
->attr
( 
   { 'xmlns:elem' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays','xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance'}
);

# create a new element
my $elem1 = SOAP::Data->new(name => 'elem:string', value => 'addedstring');

# try to add the element
push(@{$data->{array}},$elem1);

#.... send, catch, print.. bla bla bla

The code I have runs, and the WCF service see's the array just fine, but the $elem1 value is never actually appended to the SOAP envelope.

Any help is GREATLY appreciated...


Solution

  • Take a look at what $data is using Data::Dumper, you get this

    $VAR1 = bless( {
                 '_attr' => {
                              'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance',
                              'xmlns:elem' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
                            },
                 '_signature' => [],
                 '_name' => 'array',
                 '_value' => [
                               [
                                 bless( {
                                          '_value' => [
                                                        'firststring'
                                                      ],
                                          '_name' => 'string',
                                          '_prefix' => 'elem',
                                          '_signature' => [],
                                          '_attr' => {}
                                        }, 'SOAP::Data' ),
                                 bless( {
                                          '_value' => [
                                                        'secondstring'
                                                      ],
                                          '_name' => 'string',
                                          '_signature' => [],
                                          '_prefix' => 'elem',
                                          '_attr' => {}
                                        }, 'SOAP::Data' ),
                                 bless( {
                                          '_attr' => {},
                                          '_value' => [
                                                        'thridstring'
                                                      ],
                                          '_name' => 'string',
                                          '_signature' => [],
                                          '_prefix' => 'elem'
                                        }, 'SOAP::Data' )
                               ]
                             ]
               }, 'SOAP::Data' );
    

    There is no $data->{array}

    A look at the documentation for SOAP::Data, says you should use $data->value to access the array you created.

    push @{ $data->value }, $elem1;

    print Dumper $data->value;

    yields

    $VAR1 = [
          bless( {
                   '_attr' => {},
                   '_prefix' => 'elem',
                   '_value' => [
                                 'firststring'
                               ],
                   '_name' => 'string',
                   '_signature' => []
                 }, 'SOAP::Data' ),
          bless( {
                   '_signature' => [],
                   '_name' => 'string',
                   '_value' => [
                                 'secondstring'
                               ],
                   '_prefix' => 'elem',
                   '_attr' => {}
                 }, 'SOAP::Data' ),
          bless( {
                   '_name' => 'string',
                   '_signature' => [],
                   '_value' => [
                                 'thridstring'
                               ],
                   '_prefix' => 'elem',
                   '_attr' => {}
                 }, 'SOAP::Data' ),
          bless( {
                   '_attr' => {},
                   '_prefix' => 'elem',
                   '_value' => [
                                 'addedstring'
                               ],
                   '_name' => 'string',
                   '_signature' => []
                 }, 'SOAP::Data' )
        ];