SOAP :: Data :: Builder,如果没有提供值,则删除xsi:nil =“true”

时间:2011-08-15 20:37:56

标签: xml perl soap

如果我写这个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 个答案:

答案 0 :(得分:3)

这是一个解决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

答案 1 :(得分:2)

$ sb正在使用你的元素并通过xslt处理器提供它来生成SOAP消息。 你能否将“中间人”的逻辑插入到这个过程中?

就我而言,我使用wsdl生成.Net 4 C#SoapHttpClientProtocol对象,该对象有一个我能够覆盖的虚拟方法,名为GetWriterForMessage。此方法返回用于写出SOAP消息的XmlWriter对象(实质上是xslt处理器)。我能够创建一个自定义的XmlWriter,它忽略了“本地名称为nil”命令的“写出属性”。

这个解决方案的优点在于它是通用的。所以,现在它是我的库的一部分,每当我想“过滤”任何Xml输出时,我都可以使用它。它只需要一个自定义类。

看起来你的代码是c ??也许$ sb有一个指针可以设置为将'xml writer'重定向到自定义方法。

希望这有助于某人。

答案 2 :(得分:1)

您可以将SOAP生成保留在SOAP中,解析在发送端使用XML::Twig等解析器生成的代码,并使用相同的库将其打印出来,并应用您需要的选项。在接收端成功处理。

答案 3 :(得分:1)

我也遇到了同样的问题,这就是我解决问题的方法,也许也可以帮助其他人。

如果soap数据对象的值为undef,则设置'xsi:nil = true',将其设置为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' )*

预期的肥皂格式:

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

So 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的值早于undef,当更改为arrayref时,帮助我摆脱'xsi:nil = true'。

我没有必要更改任何现有的cpan模块。只需设置值arrayref而不是undef。这是perl语言的解决方案。