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

Re: [soaplite] More about Problem with WSDL file with document-literal style

Expand Messages
  • Weidong Wang
    I think I know better about the problem after some more tries. The concept of passing in multiple parameters is for rpc. When one uses a doc/literal style
    Message 1 of 4 , Jun 28, 2002
    • 0 Attachment
      I think I know better about the problem after some more tries.
       
      The concept of passing in multiple parameters is for rpc. When one uses a doc/literal style wsdl, it basically says that the body of the envelope should just be an xml document. As such, each call should just take one parameter, which should be the xml document that goes as the body element. If additional parameters are passed in, SOAP-Lite encodes them with soap encoding and add them as part of the body.
       
      I tried passing in a piece of xml document, it looks better.
       
      But, the envelope still has one more extra level. See below:
       
      <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        <SOAP-ENV:Body>
          <namesp1:GetLastTradePrice xmlns:namesp1="http://example.com/StockQuoteService/">
            <body>MSFT</body>
          </namesp1:GetLastTradePrice>
        </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>
       
      the "body" part should be the body element underneath "Body". Looks like the RPC convention is still used to generate the wrapper, then the xml document is put inside the "body" part.
       
      This seems to be incorrect, according to the WSDL spec.
       
      How do I work around it?
       
      Thanks,
       
      Weidong
       
       
      ----- Original Message -----
      Sent: Friday, June 28, 2002 1:07 PM
      Subject: Re: [soaplite] More about Problem with WSDL file with document-literal style

      More about the problem with handling a WSDL with document-literal style. I would like to know how I can make soap-lite to handle the document-literal style wsdl file and how to pass parameters (not to be soap encoded). Thanks.
       
      Attached is a simple stockquote.wsdl, which uses docuemtn-literal style.
       
      When feeding this wsdl into .NET, here is the envelope .NET generates (notice that the body value is an xml docuemtn with no soap encoding info):
       
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body>
          <TradePriceRequest xmlns="http://example.com/stockquote.xsd">
            <tickerSymbol>MSFT</tickerSymbol>
          </TradePriceRequest>
        </soap:Body>
      </soap:Envelope>
       
      When using this WSDL with SOAP-Lite, with the following code to call it:
       
      use SOAP::Lite on_debug => sub { print @_ };
       
      print SOAP::Lite
          -> service('file:stockquote.wsdl')
          -> GetLastTradePrice('MSFT');
      I got the following envelope (note the tickerSymbol part is named "body"):
       
      <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        <SOAP-ENV:Body>
          <namesp1:GetLastTradePrice xmlns:namesp1="http://example.com/StockQuoteService/">
            <body>MSFT</body>
          </namesp1:GetLastTradePrice>
        </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>
       
      And if I call with the following manner:
       
      use SOAP::Lite on_debug => sub { print @_ };
       
      $soap = SOAP::Lite
          -> service('file:stockquote.wsdl');
       
      $result = $soap->GetLastTradePrice(SOAP::Data->name(tickerSymbol => 'MSFT'));
      print $result;
      I got (notice that ticketSymbol is now encoded. Not surprise, as using SOAP::Data means soap encoding. But how do I do otherwise?):
       
      <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        <SOAP-ENV:Body>
          <namesp1:GetLastTradePrice xmlns:namesp1="http://example.com/StockQuoteService/">
            <tickerSymbol xsi:type="xsd:string">MSFT</tickerSymbol>
          </namesp1:GetLastTradePrice>
        </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>

      To unsubscribe from this group, send an email to:
      soaplite-unsubscribe@yahoogroups.com



      Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
    • Paul Kulchenko
      Hi, Weidong! ... You may use Literal serializer: BEGIN { package SOAP::Serializer::Literal; @SOAP::Serializer::Literal::ISA = SOAP::Serializer ; sub envelope
      Message 2 of 4 , Jul 1, 2002
      • 0 Attachment
        Hi, Weidong!

        > How do I work around it?
        You may use Literal serializer:

        BEGIN {
        package SOAP::Serializer::Literal;
        @SOAP::Serializer::Literal::ISA = 'SOAP::Serializer';
        sub envelope {
        my $self = shift; shift; # let it always be 'freeform'
        $self->SUPER::envelope(freeform => @_);
        }
        }

        and use it like this:

        my $data = SOAP::Data->name(body => 'MSFT')->type('');

        SOAP::Lite
        -> proxy('http://localhost/')
        -> serializer(SOAP::Serializer::Literal->new)
        -> call($data);

        This should also work with service() interface, just register the
        serializer. Let me know if you have any problems.

        Best wishes, Paul.

        --- Weidong Wang <wwang@...> wrote:
        > I think I know better about the problem after some more tries.
        >
        > The concept of passing in multiple parameters is for rpc. When one
        > uses a doc/literal style wsdl, it basically says that the body of
        > the envelope should just be an xml document. As such, each call
        > should just take one parameter, which should be the xml document
        > that goes as the body element. If additional parameters are passed
        > in, SOAP-Lite encodes them with soap encoding and add them as part
        > of the body.
        >
        > I tried passing in a piece of xml document, it looks better.
        >
        > But, the envelope still has one more extra level. See below:
        >
        > <SOAP-ENV:Envelope
        > xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        >
        > SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        > xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
        > xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
        > xmlns:xsd="http://www.w3.org/1999/XMLSchema">
        > <SOAP-ENV:Body>
        > <namesp1:GetLastTradePrice
        > xmlns:namesp1="http://example.com/StockQuoteService/">
        > <body>MSFT</body>
        > </namesp1:GetLastTradePrice>
        > </SOAP-ENV:Body>
        > </SOAP-ENV:Envelope>
        >
        > the "body" part should be the body element underneath "Body". Looks
        > like the RPC convention is still used to generate the wrapper, then
        > the xml document is put inside the "body" part.
        >
        > This seems to be incorrect, according to the WSDL spec.
        >
        > How do I work around it?
        >
        > Thanks,
        >
        > Weidong
        >
        >
        > ----- Original Message -----
        > From: Weidong Wang
        > To: soaplite@yahoogroups.com
        > Sent: Friday, June 28, 2002 1:07 PM
        > Subject: Re: [soaplite] More about Problem with WSDL file with
        > document-literal style
        >
        >
        > More about the problem with handling a WSDL with document-literal
        > style. I would like to know how I can make soap-lite to handle the
        > document-literal style wsdl file and how to pass parameters (not to
        > be soap encoded). Thanks.
        >
        > Attached is a simple stockquote.wsdl, which uses docuemtn-literal
        > style.
        >
        > When feeding this wsdl into .NET, here is the envelope .NET
        > generates (notice that the body value is an xml docuemtn with no
        > soap encoding info):
        >
        > <soap:Envelope
        > xmlns:soap=http://schemas.xmlsoap.org/soap/envelope/
        > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        > xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        > <soap:Body>
        > <TradePriceRequest xmlns="http://example.com/stockquote.xsd">
        > <tickerSymbol>MSFT</tickerSymbol>
        > </TradePriceRequest>
        > </soap:Body>
        > </soap:Envelope>
        >
        > When using this WSDL with SOAP-Lite, with the following code to
        > call it:
        >
        > use SOAP::Lite on_debug => sub { print @_ };
        >
        > print SOAP::Lite
        > -> service('file:stockquote.wsdl')
        > -> GetLastTradePrice('MSFT');
        >
        > I got the following envelope (note the tickerSymbol part is named
        > "body"):
        >
        > <SOAP-ENV:Envelope
        > xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        >
        > SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        > xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
        > xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
        > xmlns:xsd="http://www.w3.org/1999/XMLSchema">
        > <SOAP-ENV:Body>
        > <namesp1:GetLastTradePrice
        > xmlns:namesp1="http://example.com/StockQuoteService/">
        > <body>MSFT</body>
        > </namesp1:GetLastTradePrice>
        > </SOAP-ENV:Body>
        > </SOAP-ENV:Envelope>
        >
        > And if I call with the following manner:
        >
        > use SOAP::Lite on_debug => sub { print @_ };
        >
        > $soap = SOAP::Lite
        > -> service('file:stockquote.wsdl');
        >
        > $result = $soap->GetLastTradePrice(SOAP::Data->name(tickerSymbol
        > => 'MSFT'));
        > print $result;
        >
        > I got (notice that ticketSymbol is now encoded. Not surprise, as
        > using SOAP::Data means soap encoding. But how do I do otherwise?):
        >
        > <SOAP-ENV:Envelope
        > xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        >
        > SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        > xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
        > xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
        > xmlns:xsd="http://www.w3.org/1999/XMLSchema">
        > <SOAP-ENV:Body>
        > <namesp1:GetLastTradePrice
        > xmlns:namesp1="http://example.com/StockQuoteService/">
        > <tickerSymbol xsi:type="xsd:string">MSFT</tickerSymbol>
        > </namesp1:GetLastTradePrice>
        > </SOAP-ENV:Body>
        > </SOAP-ENV:Envelope>
        >
        > To unsubscribe from this group, send an email to:
        > soaplite-unsubscribe@yahoogroups.com
        >
        >
        >
        > Your use of Yahoo! Groups is subject to the Yahoo! Terms of
        > Service.
        >


        __________________________________________________
        Do You Yahoo!?
        Sign up for SBC Yahoo! Dial - First Month Free
        http://sbc.yahoo.com
      • Weidong Wang
        Thanks, Paul. This is very helpful. I am getting to generate the envelope that I want. Here is what I found out: 1. Without using a WSDL file To make
        Message 3 of 4 , Jul 2, 2002
        • 0 Attachment
          Thanks, Paul. This is very helpful. I am getting to generate the envelope
          that I want.

          Here is what I found out:

          1. Without using a WSDL file

          To make "call($data)" to work, the $data should also include the top level
          tag. In this case, it is "GetLastTradePrice". So I made it like:

          $data =
          SOAP::Data->name(GetLastTradePrice)->uri('http://example.com/StockQuoteServi
          ce/')
          ->type(ordered_hash => [tickerSymbol => SOAP::Data->type('' =>
          'MSFT')]);

          That generates the envelope body like this:

          <SOAP-ENV:Body>
          <namesp1:GetLastTradePrice
          xmlns:namesp1="http://example.com/StockQuoteService/">
          <tickerSymbol>MSFT</tickerSymbol>
          </namesp1:GetLastTradePrice>
          </SOAP-ENV:Body>

          2. Using a wsdl with service() call

          I have to call with an operation name, and in this case, the default
          serializer will generate an envelope that I don't like:

          $data = SOAP::Data->name(tickerSymbol => 'MSFT')->type('');

          SOAP::Lite
          -> service('file:stockquote.wsdl')
          -> serializer(SOAP::Serializer::Literal->new)
          -> GetLastTradePrice($data);

          <SOAP-ENV:Body>
          <c-gensym3 xsi:type="xsd:string">GetLastTradePrice</c-gensym3>
          <tickerSymbol>MSFT</tickerSymbol>
          </SOAP-ENV:Body>

          So what I did is to add another "shift" in the "envelope" sub:

          BEGIN {
          package SOAP::Serializer::Literal;
          @SOAP::Serializer::Literal::ISA = 'SOAP::Serializer';
          sub envelope {
          my $self = shift; shift; shift; # let it always be 'freeform'
          $self->SUPER::envelope(freeform => @_);
          }
          }

          and call with the data that includes the top level operation name, like the
          case to use call() in #1:

          $data =
          SOAP::Data->name(GetLastTradePrice)->uri('http://example.com/StockQuoteServi
          ce/')
          ->type(ordered_hash => [tickerSymbol => SOAP::Data->type('' =>
          'MSFT')]);

          SOAP::Lite
          -> service('file:stockquote.wsdl')
          -> serializer(SOAP::Serializer::Literal->new)
          -> GetLastTradePrice($data);

          And this generates the same envelope as in #1.

          Thanks again.

          Weidong


          ----- Original Message -----
          From: "Paul Kulchenko" <paulclinger@...>
          To: "Weidong Wang" <wwang@...>; <soaplite@yahoogroups.com>
          Sent: Tuesday, July 02, 2002 2:07 AM
          Subject: Re: [soaplite] More about Problem with WSDL file with
          document-literal style


          > Hi, Weidong!
          >
          > > How do I work around it?
          > You may use Literal serializer:
          >
          > BEGIN {
          > package SOAP::Serializer::Literal;
          > @SOAP::Serializer::Literal::ISA = 'SOAP::Serializer';
          > sub envelope {
          > my $self = shift; shift; # let it always be 'freeform'
          > $self->SUPER::envelope(freeform => @_);
          > }
          > }
          >
          > and use it like this:
          >
          > my $data = SOAP::Data->name(body => 'MSFT')->type('');
          >
          > SOAP::Lite
          > -> proxy('http://localhost/')
          > -> serializer(SOAP::Serializer::Literal->new)
          > -> call($data);
          >
          > This should also work with service() interface, just register the
          > serializer. Let me know if you have any problems.
          >
          > Best wishes, Paul.
          >
        Your message has been successfully submitted and would be delivered to recipients shortly.