Я борюсь с Perl (v5.24.1) SOAP :: Lite. я пытаюсь добавить элемент в
существующий элемент данных.
Предположим, у меня есть следующая конструкция:
use SOAP::Lite + qw/ trace /;
my $soap = SOAP::Lite->new( proxy => 'http://soap.server.com');
$soap->on_action( sub { "http://tempuri.org/some" });
$soap->autotype(0)->readable(1);
$soap->default_ns('http://tempuri.org/');
$som = $soap->call('GetItems', SOAP::Data->name('Store')->attr( { 'xmlns' => 'Some.Structs'} )->value(
\SOAP::Data->value(
SOAP::Data->name('Items')->value(
\SOAP::Data->value(
SOAP::Data->name('Available')->value('false'),
SOAP::Data->name('Apple')->value('1'),
SOAP::Data->name('Orange')->value('2'),
)),
)),
);
Но теперь я хотел бы добавить N элементов Предметы, я хочу сделать это в цикле на основе условий, так что это просто пример, я пробовал следующее:
use SOAP::Lite + qw/ trace /;
my $soap = SOAP::Lite->new( proxy => 'http://soap.server.com');
$soap->on_action( sub { "http://tempuri.org/some" });
$soap->autotype(0)->readable(1);
$soap->default_ns('http://tempuri.org/');
my $data1= (SOAP::Data->name('Store')->attr( { 'xmlns' => 'Some.Structs'} )->value(
\SOAP::Data->value(
SOAP::Data->name('Items')->value(
\SOAP::Data->value(
SOAP::Data->name('Available')->value('false'),
SOAP::Data->name('Apple')->value('1'),
SOAP::Data->name('Orange')->value('2'),
)),
)),
);
my $data2= (SOAP::Data->name('Store')->attr( { 'xmlns' => 'Some.Structs'} )->value(
\SOAP::Data->value(
SOAP::Data->name('Items')->value(
\SOAP::Data->value(
SOAP::Data->name('Available')->value('true'),
SOAP::Data->name('Bananas')->value('4'),
SOAP::Data->name('Pineapple')->value('2'),
)),
)),
);
Теперь пытаемся добавить элемент
push $data1->value, data2;
Или
push ($data1,$data1);
Возврат: Экспериментальное нажатие на скаляр теперь запрещено ....
Наконец, когда элементы соединяются, я хотел бы их отправить, но не уверен, что это сработает:
$som = $soap->call('GetItems', $data1);
Любая помощь приветствуется ....





Ответ в Добавить элемент к уже существующему сложному типу SOAP :: Data использовал экспериментальный стиль разыменования (теперь исправлено). Вам необходимо использовать следующий синтаксис:
push @{ $data1->value }, $data2
Чтобы добавить в список Items постфактум, вы можете использовать следующий подход, который вручную просматривает структуру данных, которую вы создали выше, и добавляет в соответствующий список:
push @{ ${ ${ $data1->value }->value->value }->{_value} }, $data2;
Но я думаю, что вам будет намного лучше, если вы создадите свои данные SOAP только после того, как соберете все данные полезной нагрузки. В случае цикла вместо этого структурируйте вашу программу следующим образом:
my @payload;
for my $item (@items) {
push @payload, SOAP::Data->name( $item->{name} )->value( $item->{count}) if $item->{wanted};
};
my $soap = SOAP::Data->value( \@payload );
В приведенном выше примере я попробовал
push @{ $data1->value }, $data2;
Но это приводит к
Not an ARRAY reference at ..
Как было предложено выше, я буду строить свои данные следующим образом:
my @payload;
push @payload, SOAP::Data->name('Store')->attr( { 'xmlns' => 'Some.Structs'}
)->value(
\SOAP::Data->value(
SOAP::Data->name('Items')->value(
\SOAP::Data->value(
SOAP::Data->name('Available')->value('false'),
SOAP::Data->name('Apple')->value('1'),
SOAP::Data->name('Orange')->value('2'),
)),
));
#Now add the next element
push @payload, SOAP::Data->name('Store')->attr( { 'xmlns' => 'Some.Structs'}
)->value(
\SOAP::Data->value(
SOAP::Data->name('Items')->value(
\SOAP::Data->value(
SOAP::Data->name('Available')->value('false'),
SOAP::Data->name('Orange')->value('1'),
SOAP::Data->name('Pianaple')->value('2'),
)),
));
$som = $soap->call('GetItems', \@payload);
Насколько я понимаю SOAP :: Data, вы не сможете впоследствии решить, что хотите преобразовать скалярный элемент в элемент списка. Если вы действительно намерены добавить в список
Items, то вам нужно пройти по созданной структуре данных и исправить это значение (см. Мой обновленный ответ выше)