如果我写这个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" />
我知道哪些有效,我只是想不出如何生成它。
答案 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语言的解决方案。