Loading ...
Sorry, an error occurred while loading the content.

Re: SOAP::Lite / GLUE / Deserializer

Expand Messages
  • Paul Kulchenko
    Hi, Leon! I CC-ed SOAP::Lite s list because it might be interesting for others. ... Thanks ;) ... There are two main ways of writing deserializer. You can put
    Message 1 of 1 , Nov 27, 2001
    • 0 Attachment
      Hi, Leon!

      I CC-ed SOAP::Lite's list because it might be interesting for others.

      --- Leon Brocard <leon@...> wrote:
      > Just thought I'd let you know that SOAP::Lite rocks...
      Thanks ;)

      > %vector
      > item => OpenFrame::Session
      >
      > Whereas a Vector is really a dynamic array in Java, so I'd ideally
      > like
      > an arrayref ["OpenFrame::AbstractRequest", "OpenFrame::Session"].
      > What I don't quite understand is how to write a custom SOAP::Lite
      > deserializer.

      There are two main ways of writing deserializer. You can put your
      method in SOAP::Deserializer package and in this case ANY type with
      specific name will be handled by that method. For example:

      sub SOAP::Deserializer::as_myclass {}

      will handle
      <a xsi:type="ns1:myclass" xmlns:ns1="abc"/>

      as well as
      <b xsi:type="ns1:myclass" xmlns:ns1="def"/> # <<< different namespace

      which may be not exactly what you want/need.

      You can also create as_myclass in specific package and then bind
      namespace to that package:

      sub TheMindElectric::as_myclass {}

      $d = SOAP::Deserializer->new;
      $d->xmlschemas->{'abc'} = 'TheMindElectric';

      In this case TheMindElectric::as_myclass will be called for
      <a xsi:type="ns1:myclass" xmlns:ns1="abc"/>

      but not for:
      <b xsi:type="ns1:myclass" xmlns:ns1="def"/>

      In your case code may look like:

      sub SOAP::Deserializer::as_vector {
      my($self, $value, $name, $attrs, $children, $type) = @_;
      [map { scalar(($self->decode_object($_))[1]) } @{$children || []}];
      }

      -- OR --

      sub TheMindElectric::as_vector {
      my($self, $value, $name, $attrs, $children, $type) = @_;
      [map { scalar(($self->decode_object($_))[1]) } @{$children || []}];
      }

      # register package for namespace ($d is your deserializer)
      $d->xmlschemas->{'http://www.themindelectric.com/collections/'} =
      'TheMindElectric';

      You can definitely do both, TheMindElectric::as_vector will be called
      for 'vector' type in TheMindElectric's namespace and
      SOAP::Deserializer::as_vector method will be called for all other
      'vector' types. You can also bind several namespaces to one package.
      You should also be able to use object instead of package if you need
      that.

      Parameters of as_* methods are not well documented, because they are
      still subject to change, but I don't foresee any major changes in the
      next version in this aspect.

      There is also an example of this method in examples/customschema.pl.

      Let me know if you have any questions or find any problems.

      Best wishes, Paul.

      --- Leon Brocard <leon@...> wrote:
      > ... but I'm having a problem getting it to talk to a GLUE server
      > which
      > is returning a Java Vector object. The envelope (which seems
      > correct)
      > that is getting returned is:
      >
      > HTTP/1.1 200 OK
      > Date: Tue, 27 Nov 2001 17:53:21 GMT
      > Content-Type: text/xml; charset=UTF-8
      > Server: GLUE/1.3
      > Content-Length: 686
      >
      > <?xml version='1.0' encoding='UTF-8'?>
      > <soap:Envelope
      > xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance'
      > xmlns:xsd='http://www.w3.org/1999/XMLSchema'
      > xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'
      > xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
      >
      soap:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'><soap:Body><n:whatResponse
      > xmlns:n='http://tempuri.org/Time'><Result
      > href='#id0'/></n:whatResponse><id0 id='id0' soapenc:root='0'
      > xmlns:ns2='http://www.themindelectric.com/collections/'
      > xsi:type='ns2:vector'><item
      > xsi:type='xsd:string'>OpenFrame::AbstractRequest</item><item
      >
      xsi:type='xsd:string'>OpenFrame::Session</item></id0></soap:Body></soap:Envelope>
      >
      > The SOAP::Lite deserializer turns this into a hash ref
      > (Data::Denter
      > output):
      >
      > %vector
      > item => OpenFrame::Session
      >
      > Whereas a Vector is really a dynamic array in Java, so I'd ideally
      > like
      > an arrayref ["OpenFrame::AbstractRequest", "OpenFrame::Session"].
      > What I
      > don't quite understand is how to write a custom SOAP::Lite
      > deserializer.
      > What does the deserializer actually do?
      >
      > Cheers, Leon
      > --
      > .soapy?
      >


      __________________________________________________
      Do You Yahoo!?
      Yahoo! GeoCities - quick and easy web site hosting, just $8.95/month.
      http://geocities.yahoo.com/ps/info1
    Your message has been successfully submitted and would be delivered to recipients shortly.