SOAP :: Data :: Builder, remove xsi: nil = "true" if not specified

If I write this SOAP :: Data :: Builder code (where $sb is the SOAP :: Data :: Builder object)

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

it generates the following

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

This is unacceptable because xsi: nil causes problems on the receiving side. However, if I uncomment the commented line, I get

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

Technically this works, so this is a workaround. But in the end I would like

 <ccAuthService run="true" /> 

What I know works, I just can't figure out how to create it.

+4
source share
4 answers

This is a solution to fix this problem using SOAP :: Lite (which uses SOAP :: Data :: Builder).

Define the following in your code:

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

To use this type:

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

Some hints of this in SOAP :: Serializer .

+2
source

$ sb takes your item and passes it through the xslt processor to create the SOAP message. Can you include the logic of the “average person” in this process?

In my case, I used wsdl to create a .Net 4 C # SoapHttpClientProtocol object, which has a virtual method that I could override, called GetWriterForMessage. This method returns the XmlWriter object used to write the SOAP message (essentially the xslt processor). I managed to create a custom XmlWriter that ignored "write out attributes whose local name was nil".

What's good about THIS solution is universal. So now this is part of my library that I can use whenever I want to "filter" any Xml output. And he took only one user class.

Looks like your c ?? code Maybe $ sb has a pointer that you can configure to redirect "xml writer" to your own method.

Hope this helps someone.

+1
source

You can leave the XML generation in SOAP as it is, parse the code generated by the parser, for example XML::Twig at the end of the submission, and print it using the same library, using the parameters necessary for its successful processing on the receiving side .

0
source

I also had the same problem, and this is how I solved it, maybe it can also help others.

"xsi: nil = true" is set, if the value of the soap data object is undef, set it to arrayref to solve the problem.

See below code for reference:

Soap format:

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

The structure of the soap object

 *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' )* 

Expected soap format:

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

So, the structure of the Soap object should be:

 *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' )* 

If you closely monitor objects, the HotelIdInfo value was not previously before, which, when changing to arrayref, helped me get rid of "xsi: nil = true".

I did not have to change any of the existing cpan modules. Just set the value of arrayref instead of undef. This solution is in perl.

0
source

All Articles