SOAP :: Data :: Builder, удалить xsi: nil = "true", если значение не указано - PullRequest
5 голосов
/ 16 августа 2011

Если я напишу этот SOAP :: Data :: Builder код (где $sb - это объект SOAP :: Data :: Builder)

    $sb->add_elem(
        attributes => { run => 'true' },
        name       => 'ccAuthService',
#       value      => ' ', # hack to prevent cs side unparseable xml
    );

, он генерирует следующее

<ccAuthService xsi:nil="true" run="true" />

Что недопустимо, поскольку xsi: nil вызывает проблемы на приемном конце.Однако, если я раскомментирую закомментированную строку, я получу

<ccAuthService run="true"> </ccAuthService>

Технически это работает, так что это обходной путь.Но в конечном итоге я хотел бы получить

<ccAuthService run="true" />

Я знаю, что это работает, я просто не могу понять, как его генерировать.

Ответы [ 4 ]

3 голосов
/ 19 февраля 2013

Это решение для устранения этой проблемы с помощью SOAP :: Lite (которую использует SOAP :: Data :: Builder).

Определите следующее где-то в вашем коде:

sub SOAP::Serializer::as_nonil
{
    my ($self, $value, $name, $type, $attr) = @_;
    delete $attr->{'xsi:nil'};
    return [ $name, $attr, $value ];
}

Для использования этого типа:

SOAP::Data->new(
   type => 'nonil',
   name => 'ping',
   prefix => '',
   uri => 'http://myschema.domain/',
);

Некоторые подсказки по этому поводу содержатся в SOAP :: Serializer .

2 голосов
/ 18 февраля 2012

$ sb берет ваш элемент и передает его через процессор xslt для генерации SOAP-сообщения. Можете ли вы вставить в этот процесс логику «среднего человека»?

В моем случае я использовал wsdl для создания объекта .Net 4 C # SoapHttpClientProtocol, в котором есть виртуальный метод, который я смог переопределить, называется GetWriterForMessage. Этот метод возвращает объект XmlWriter, используемый для записи сообщения SOAP (по сути, процессор xslt). Мне удалось создать пользовательский XmlWriter, который игнорировал команды «записать атрибуты, локальное имя которых было равно nil».

Что хорошего в этом решении, так это то, что оно универсальное. Итак, теперь это часть моей библиотеки, которую я могу использовать всякий раз, когда хочу «отфильтровать» любой вывод XML. И это заняло только один пользовательский класс.

Похоже, ваш код c ?? Возможно, у $ sb есть указатель, который вы можете установить для перенаправления его «XML Writer» на пользовательский метод.

Надеюсь, это кому-нибудь поможет.

1 голос
/ 26 декабря 2012

У меня тоже была такая же проблема, и вот как я ее решил, может быть, это может помочь и другим.

'xsi: nil = true' устанавливается, если значение объекта данных мыла равно undefустановите значение arrayref для решения проблемы.

См. код ниже для справки:

Формат мыла:

< m:clHotelIdInfo>< m:HotelIdInfo xsi:nil=true  id="1219615" />< /m:clHotelIdInfo>

Структура объекта мыла

*bless( {
     '_name' => 'clHotelIdInfo',
     '_signature' => [],
     '_value' => [
                   \bless( {
                              '_signature' => [],
                              '_value' => [
                                            bless( {
                                                     '_name' => 'HotelIdInfo',
                                                     '_signature' => [],
                                                     **'_value' => [
                                                                   undef
                                                                 ],**
                                                     '_prefix' => 'm',
                                                     '_attr' => {
                                                                  'id' => '1219615'
                                                                }
                                                   }, 'SOAP::Data' )
                                          ],
                              '_attr' => {}
                            }, 'SOAP::Data' )
                 ],
     '_prefix' => 'm',
     '_attr' => {}
 }, 'SOAP::Data' )*

Ожидаемый формат Soap:

< m:clHotelIdInfo>< m:HotelIdInfo id="1219615" /></ m:clHotelIdInfo>                                                         

Структура объекта Soap должна быть:

*bless( {
         '_name' => 'clHotelIdInfo',
         '_signature' => [],
         '_value' => [
                       \bless( {
                                  '_signature' => [],
                                  '_value' => [
                                                bless( {
                                                         '_name' => 'HotelIdInfo',
                                                         '_signature' => [],
                                                         **'_value' => [],**
                                                         '_prefix' => 'm',
                                                         '_attr' => {
                                                                      'id' => '1219615'
                                                                    }
                                                       }, 'SOAP::Data' )
                                              ],
                                  '_attr' => {}
                                }, 'SOAP::Data' )
                     ],
         '_prefix' => 'm',
         '_attr' => {}
}, 'SOAP::Data' )*

Если вы внимательно наблюдаете за объектами, значение HotelIdInfo было ранее неопределенным, которое при изменении наarrayref, помог мне избавиться от 'xsi: nil = true'.

Мне не пришлось менять ни один из существующих модулей cpan.Просто установите значение arrayref вместо undef.Это решение на языке Perl.

1 голос
/ 16 августа 2011

Вы можете оставить генерацию XML в SOAP как есть, проанализировать код, сгенерированный с помощью синтаксического анализатора, такого как XML::Twig, на отправляющей стороне, и распечатать его с той же библиотекой, применяя параметры, необходимые для успешной обработки. на приемном конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...