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

HOWTO: literal serialization

Expand Messages
  • Alberto Accomazzi
    I just figured out a little hack that makes it possible to use your existing SOAP::Lite code to create a message with literal encoding (rather than the SOAP
    Message 1 of 3 , May 20, 2003
    • 0 Attachment
      I just figured out a little hack that makes it possible to use your
      existing SOAP::Lite code to create a message with literal encoding
      (rather than the SOAP encoding that SOAP::Lite uses by default). So I
      thought I'd share the info with people on the mailing list and see if
      somebody has some suggestions on how this can be improved.

      Basically all you need to do is override the xmlize() and envelope()
      methods so that all the attributes used for the SOAP encoding are
      stripped and the default namespace is added to the method element within
      the body.

      What my hack does _not_ do is set the proper namespace to reflect the
      fact that we're using literal encoding (i.e. the SOAP envelope still has
      xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" in it). Does
      anybody know how to do this?

      The synopsis for the literal encoding is below. Working examples of
      SOAP client and server scripts are available under the url
      http://ads.harvard.edu/~alberto/SOAP


      -- Alberto



      my $uri = 'urn:foo';
      my $service = SOAP::Lite
      ->proxy('http://whatever.com/service.cgi')
      ->serializer(LiteralSerializer->new)
      ->uri($uri);
      #...

      BEGIN {
      package LiteralSerializer;
      @LiteralSerializer::ISA = 'SOAP::Serializer';
      sub xmlize {
      my $self = shift;
      my($name, $attrs, $values, $id) = @{+shift};
      $attrs ||= {};

      # keep only namespace attributes for all elements
      my $a = $attrs->{xmlns} ? {xmlns => $attrs->{xmlns}} : {};

      return $self->SUPER::xmlize([$name, $a, $values, $id]);
      }
      sub envelope {
      $_[2] = (UNIVERSAL::isa($_[2] => 'SOAP::Data') ? $_[2] :
      SOAP::Data->name($_[2])->attr({xmlns => $uri}))
      if $_[1] =~ /^(?:method|response)$/;
      shift->SUPER::envelope(@_);
      }
      }



      ****************************************************************************
      Alberto Accomazzi
      NASA Astrophysics Data System http://adswww.harvard.edu
      Harvard-Smithsonian Center for Astrophysics http://cfa-www.harvard.edu
      60 Garden Street, MS 83, Cambridge, MA 02138 USA
      ****************************************************************************
    • Alberto Accomazzi
      Jonathan, using your approach of creating elements via SOAP::Data calls I still don t see a way to avoid having xsi data types within the XML when you re
      Message 2 of 3 , May 23, 2003
      • 0 Attachment
        Jonathan,

        using your approach of creating elements via SOAP::Data calls I still
        don't see a way to avoid having xsi data types within the XML when
        you're sending across hashes and arrays. For instance, the example
        client script I have posted under http://ads.harvard.edu/~alberto/SOAP
        generates the following XML when I use the --literal option and give it
        the command line arguments of "foo" "bar":

        <verify xmlns="http://ads.harvard.edu/DataVerifier">
        <verifyRequest>
        <header>
        <protocolversion>0.3</protocolversion>
        </header>
        <identifiers>
        <item>foo</item>
        <item>bar</item>
        </identifiers>
        </verifyRequest>
        </verify>

        whereas if you don't use the --literal option (i.e. you use the default
        serializer) you get this:

        <verify xmlns="http://ads.harvard.edu/DataVerifier">
        <verifyRequest>
        <header xsi:type="namesp1:SOAPStruct">
        <protocolversion xsi:type="xsd:float">0.2</protocolversion>
        </header>
        <identifiers xsi:type="SOAP-ENC:Array"
        SOAP-ENC:arrayType="xsd:string[1]">
        <item xsi:type="xsd:string">foo</item>
        <item xsi:type="xsd:string">foo</item>
        </identifiers>
        </verifyRequest>
        </verify>

        I've played with maptype() and the like, but haven't found any other way
        of removing the attributes for arrays and hashes.

        The reason for doing this, BTW, is to be able to write clients and
        servers that interoperate well with those SOAP toolkits that insist in
        strict schema validation, rejecting an incoming query if it contains the
        type attributes.

        -- Alberto


        jpeyser wrote:
        > Alberto,
        > There is a more straightforward way to insert your own
        > literals. This is from the SOAP::Lite man page
        >
        > print SOAP::Lite
        > -> new(....)
        > -> call(SOAP::Data->name('method')->attr({xmlns
        > => 'mynamespace'})
        > => @parameters)
        > -> result;
        >
        > For example, when calling getQuote for a stock quote
        >
        > my $s = SOAP::Lite
        > -> uri('urn:xmethods-delayed-quotes')
        > -> proxy('http://services.xmethods.net/soap')
        > ;
        >
        > $r = $s->call(SOAP::Data->name('xyz:getQuote')
        > ->attr({'xmlns:xyz' => 'urn:xmethods-delayed-
        > quotes'})
        > => SOAP::Data->name('Symbol' => $symbol));
        >
        > Where necessary, the data can be scoped using ->prefix(‘xyz’).
        > Your hack would be helpful with arrays.
        >
        > Don’t mean to discourage your hacking the code. I’ve done some myself.
        >
        > Jonathan
        >
        >
        >
        > --- In soaplite@yahoogroups.com, Alberto Accomazzi <aaccomazzi@c...>
        > wrote:
        >
        >>I just figured out a little hack that makes it possible to use your
        >>existing SOAP::Lite code to create a message with literal encoding
        >>(rather than the SOAP encoding that SOAP::Lite uses by default).
        >
        > So I
        >
        >>thought I'd share the info with people on the mailing list and see
        >
        > if
        >
        >>somebody has some suggestions on how this can be improved.
        >>
        >>Basically all you need to do is override the xmlize() and envelope
        >
        > ()
        >
        >>methods so that all the attributes used for the SOAP encoding are
        >>stripped and the default namespace is added to the method element
        >
        > within
        >
        >>the body.
        >>
        >>What my hack does _not_ do is set the proper namespace to reflect
        >
        > the
        >
        >>fact that we're using literal encoding (i.e. the SOAP envelope
        >
        > still has
        >
        >>xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" in it).
        >
        > Does
        >
        >>anybody know how to do this?
        >>
        >>The synopsis for the literal encoding is below. Working examples
        >
        > of
        >
        >>SOAP client and server scripts are available under the url
        >>http://ads.harvard.edu/~alberto/SOAP
        >>
        >>
        >>-- Alberto
        >>
        >>
        >>
        >>my $uri = 'urn:foo';
        >>my $service = SOAP::Lite
        >> ->proxy('http://whatever.com/service.cgi')
        >> ->serializer(LiteralSerializer->new)
        >> ->uri($uri);
        >>#...
        >>
        >>BEGIN {
        >> package LiteralSerializer;
        >> @LiteralSerializer::ISA = 'SOAP::Serializer';
        >> sub xmlize {
        >> my $self = shift;
        >> my($name, $attrs, $values, $id) = @{+shift};
        >> $attrs ||= {};
        >>
        >> # keep only namespace attributes for all elements
        >> my $a = $attrs->{xmlns} ? {xmlns => $attrs->{xmlns}} : {};
        >>
        >> return $self->SUPER::xmlize([$name, $a, $values, $id]);
        >> }
        >> sub envelope {
        >> $_[2] = (UNIVERSAL::isa($_[2] => 'SOAP::Data') ? $_[2] :
        >> SOAP::Data->name($_[2])->attr({xmlns => $uri}))
        >> if $_[1] =~ /^(?:method|response)$/;
        >> shift->SUPER::envelope(@_);
        >> }
        >>}
        >>
        >>
        >>
        >>
        >
        > **********************************************************************
        > ******
        >
        >>Alberto Accomazzi
        >>NASA Astrophysics Data System
        >
        > http://adswww.harvard.edu
        >
        >>Harvard-Smithsonian Center for Astrophysics http://cfa-
        >
        > www.harvard.edu
        >
        >>60 Garden Street, MS 83, Cambridge, MA 02138 USA
        >>
        >
        > **********************************************************************
        > ******


        --

        ****************************************************************************
        Alberto Accomazzi
        NASA Astrophysics Data System http://adswww.harvard.edu
        Harvard-Smithsonian Center for Astrophysics http://cfa-www.harvard.edu
        60 Garden Street, MS 83, Cambridge, MA 02138 USA
        ****************************************************************************
      • edwardshallow
        Byrne and Paul, This is just one of the numerous posts on the need for better document/literal handling in SOAP::Lite. Microsoft s latest products, Office2003,
        Message 3 of 3 , Sep 19, 2003
        • 0 Attachment
          Byrne and Paul,

          This is just one of the numerous posts on the need for better
          document/literal handling in SOAP::Lite.

          Microsoft's latest products, Office2003, InfoPath, etc ... which
          boast WebService invocation capabilities WILL NOT EVEN ACCEPT a WSDL
          which is rpc-based IT MUST BE document/literal.

          This inter-op question is no longer simply an annoyance with
          SOAP::Lite. It is (IMHO) becoming critical to SOAP::Lite's future.

          Please let us now how you will address this need in upcomning
          releases (or if you have already ???), and kindly post some solid
          recommendations for the interim while we wait.

          A still happy and long-time SOAP::Lite user,
          Ed




          --- In soaplite@yahoogroups.com, Alberto Accomazzi <aaccomazzi@c...>
          wrote:
          > Jonathan,
          >
          > using your approach of creating elements via SOAP::Data calls I
          still
          > don't see a way to avoid having xsi data types within the XML when
          > you're sending across hashes and arrays. For instance, the
          example
          > client script I have posted under
          http://ads.harvard.edu/~alberto/SOAP
          > generates the following XML when I use the --literal option and
          give it
          > the command line arguments of "foo" "bar":
          >
          > <verify xmlns="http://ads.harvard.edu/DataVerifier">
          > <verifyRequest>
          > <header>
          > <protocolversion>0.3</protocolversion>
          > </header>
          > <identifiers>
          > <item>foo</item>
          > <item>bar</item>
          > </identifiers>
          > </verifyRequest>
          > </verify>
          >
          > whereas if you don't use the --literal option (i.e. you use the
          default
          > serializer) you get this:
          >
          > <verify xmlns="http://ads.harvard.edu/DataVerifier">
          > <verifyRequest>
          > <header xsi:type="namesp1:SOAPStruct">
          > <protocolversion xsi:type="xsd:float">0.2</protocolversion>
          > </header>
          > <identifiers xsi:type="SOAP-ENC:Array"
          > SOAP-ENC:arrayType="xsd:string[1]">
          > <item xsi:type="xsd:string">foo</item>
          > <item xsi:type="xsd:string">foo</item>
          > </identifiers>
          > </verifyRequest>
          > </verify>
          >
          > I've played with maptype() and the like, but haven't found any
          other way
          > of removing the attributes for arrays and hashes.
          >
          > The reason for doing this, BTW, is to be able to write clients and
          > servers that interoperate well with those SOAP toolkits that
          insist in
          > strict schema validation, rejecting an incoming query if it
          contains the
          > type attributes.
          >
          > -- Alberto
          >
          >
          > jpeyser wrote:
          > > Alberto,
          > > There is a more straightforward way to insert your own
          > > literals. This is from the SOAP::Lite man page
          > >
          > > print SOAP::Lite
          > > -> new(....)
          > > -> call(SOAP::Data->name('method')->attr({xmlns
          > > => 'mynamespace'})
          > > => @parameters)
          > > -> result;
          > >
          > > For example, when calling getQuote for a stock quote
          > >
          > > my $s = SOAP::Lite
          > > -> uri('urn:xmethods-delayed-quotes')
          > > -> proxy('http://services.xmethods.net/soap')
          > > ;
          > >
          > > $r = $s->call(SOAP::Data->name('xyz:getQuote')
          > > ->attr({'xmlns:xyz' => 'urn:xmethods-delayed-
          > > quotes'})
          > > => SOAP::Data->name('Symbol' => $symbol));
          > >
          > > Where necessary, the data can be scoped using ->prefix
          (‘xyz’).
          > > Your hack would be helpful with arrays.
          > >
          > > Don’t mean to discourage your hacking the code. I’ve done
          some myself.
          > >
          > > Jonathan
          > >
          > >
          > >
          > > --- In soaplite@yahoogroups.com, Alberto Accomazzi
          <aaccomazzi@c...>
          > > wrote:
          > >
          > >>I just figured out a little hack that makes it possible to use
          your
          > >>existing SOAP::Lite code to create a message with literal
          encoding
          > >>(rather than the SOAP encoding that SOAP::Lite uses by
          default).
          > >
          > > So I
          > >
          > >>thought I'd share the info with people on the mailing list and
          see
          > >
          > > if
          > >
          > >>somebody has some suggestions on how this can be improved.
          > >>
          > >>Basically all you need to do is override the xmlize() and
          envelope
          > >
          > > ()
          > >
          > >>methods so that all the attributes used for the SOAP encoding
          are
          > >>stripped and the default namespace is added to the method
          element
          > >
          > > within
          > >
          > >>the body.
          > >>
          > >>What my hack does _not_ do is set the proper namespace to
          reflect
          > >
          > > the
          > >
          > >>fact that we're using literal encoding (i.e. the SOAP envelope
          > >
          > > still has
          > >
          > >>xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" in
          it).
          > >
          > > Does
          > >
          > >>anybody know how to do this?
          > >>
          > >>The synopsis for the literal encoding is below. Working
          examples
          > >
          > > of
          > >
          > >>SOAP client and server scripts are available under the url
          > >>http://ads.harvard.edu/~alberto/SOAP
          > >>
          > >>
          > >>-- Alberto
          > >>
          > >>
          > >>
          > >>my $uri = 'urn:foo';
          > >>my $service = SOAP::Lite
          > >> ->proxy('http://whatever.com/service.cgi')
          > >> ->serializer(LiteralSerializer->new)
          > >> ->uri($uri);
          > >>#...
          > >>
          > >>BEGIN {
          > >> package LiteralSerializer;
          > >> @LiteralSerializer::ISA = 'SOAP::Serializer';
          > >> sub xmlize {
          > >> my $self = shift;
          > >> my($name, $attrs, $values, $id) = @{+shift};
          > >> $attrs ||= {};
          > >>
          > >> # keep only namespace attributes for all elements
          > >> my $a = $attrs->{xmlns} ? {xmlns => $attrs->{xmlns}} :
          {};
          > >>
          > >> return $self->SUPER::xmlize([$name, $a, $values, $id]);
          > >> }
          > >> sub envelope {
          > >> $_[2] = (UNIVERSAL::isa($_[2] => 'SOAP::Data') ? $_[2] :
          > >> SOAP::Data->name($_[2])->attr({xmlns => $uri}))
          > >> if $_[1] =~ /^(?:method|response)$/;
          > >> shift->SUPER::envelope(@_);
          > >> }
          > >>}
          > >>
          > >>
          > >>
          > >>
          > >
          > >
          *********************************************************************
          *
          > > ******
          > >
          > >>Alberto Accomazzi
          > >>NASA Astrophysics Data System
          > >
          > > http://adswww.harvard.edu
          > >
          > >>Harvard-Smithsonian Center for Astrophysics http://cfa-
          > >
          > > www.harvard.edu
          > >
          > >>60 Garden Street, MS 83, Cambridge, MA 02138 USA
          > >>
          > >
          > >
          *********************************************************************
          *
          > > ******
          >
          >
          > --
          >
          >
          *********************************************************************
          *******
          > Alberto Accomazzi
          > NASA Astrophysics Data System
          http://adswww.harvard.edu
          > Harvard-Smithsonian Center for Astrophysics http://cfa-
          www.harvard.edu
          > 60 Garden Street, MS 83, Cambridge, MA 02138 USA
          >
          *********************************************************************
          *******
        Your message has been successfully submitted and would be delivered to recipients shortly.