WSDL help.... possibly a complexTypes issue

From: Date: Fri, 03 Feb 2006 17:59:43 +0000
Subject: WSDL help.... possibly a complexTypes issue
Groups: php.soap 
Request: Send a blank email to php-soap+get-2111@lists.php.net to get a copy of this message
I'm trying to evaluate some non-Axis 1.1 SOAP services that are also servlet-based. One of the requirements is that they support PHP clients. The one I've found that I'm liking best so far is called XFire. I've used its example project to create a web service that generates the following WSDL: <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://demo.xfire.codehaus.org" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://xfire.codehaus.org/BookService" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xfire.codehaus.org/BookService"> <wsdl:types>
    <xsd:schema targetNamespace="http://xfire.codehaus.org/BookService" elementFormDefault="qualified" attributeFormDefault="qualified">
      <xsd:element name="getBooks">
        <xsd:complexType />
      </xsd:element>
      <xsd:element name="getBooksResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="out" type="ns1:ArrayOfBook" minOccurs="1" maxOccurs="1" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="findBook">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="in0" type="xsd:string" minOccurs="1" maxOccurs="1" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="findBookResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="out" type="ns1:Book" minOccurs="1" maxOccurs="1" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
    <xsd:schema targetNamespace="http://demo.xfire.codehaus.org" elementFormDefault="qualified" attributeFormDefault="qualified">
      <xsd:complexType name="ArrayOfBook">
        <xsd:sequence>
          <xsd:element name="Book" type="ns1:Book" nillable="true" minOccurs="0" maxOccurs="unbounded" />
        </xsd:sequence>
      </xsd:complexType>
      <xsd:complexType name="Book">
        <xsd:sequence>
          <xsd:element name="author" type="xsd:string" nillable="true" />
          <xsd:element name="isbn" type="xsd:string" nillable="true" />
          <xsd:element name="title" type="xsd:string" nillable="true" />
        </xsd:sequence>
      </xsd:complexType>
    </xsd:schema>
</wsdl:types> <wsdl:message name="getBooksRequest">
    <wsdl:part element="tns:getBooks" name="parameters" />
</wsdl:message> <wsdl:message name="findBookRequest">
    <wsdl:part element="tns:findBook" name="parameters" />
</wsdl:message> <wsdl:message name="findBookResponse">
    <wsdl:part element="tns:findBookResponse" name="parameters" />
</wsdl:message> <wsdl:message name="getBooksResponse">
    <wsdl:part element="tns:getBooksResponse" name="parameters" />
</wsdl:message> <wsdl:portType name="BookServicePortType">
    <wsdl:operation name="getBooks">
      <wsdl:input message="tns:getBooksRequest" name="getBooksRequest" />
      <wsdl:output message="tns:getBooksResponse" name="getBooksResponse" />
    </wsdl:operation>
    <wsdl:operation name="findBook">
      <wsdl:input message="tns:findBookRequest" name="findBookRequest" />
      <wsdl:output message="tns:findBookResponse" name="findBookResponse" />
    </wsdl:operation>
</wsdl:portType> <wsdl:binding name="BookServiceHttpBinding" type="tns:BookServicePortType">
    <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getBooks">
      <wsdlsoap:operation soapAction="" />
      <wsdl:input name="getBooksRequest">
        <wsdlsoap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="getBooksResponse">
        <wsdlsoap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="findBook">
      <wsdlsoap:operation soapAction="" />
      <wsdl:input name="findBookRequest">
        <wsdlsoap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="findBookResponse">
        <wsdlsoap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
</wsdl:binding> <wsdl:service name="BookService">
    <wsdl:port binding="tns:BookServiceHttpBinding" name="BookServiceHttpPort">
      <wsdlsoap:address location="http://localhost:8080/xfire-demo/services/BookService" />
    </wsdl:port>
</wsdl:service> </wsdl:definitions> Now, I'm not an expert with this, but the WSDL looks right to me, and to some extent it is... the following code works:
    $bookService = new SoapClient(
        "http://localhost:8080/xfire-demo/services/BookService?wsdl",
        array( 'trace' => 1 ) );
    $books = $bookService->getBooks();
    print_r( $books );
However, the other function does not. The following code breaks:
    $bookService = new SoapClient(
        "http://localhost:8080/xfire-demo/services/BookService?wsdl",
        array( 'trace' => 1 ) );
    $searchBook = "0123456789";
    $onlyBook = $bookService->findBook( $searchBook );
    print_r( $onlyBook );
When calling findBook(), I get the following SoapFault: object(SoapFault)#7 (9) { ["message:protected"]=> string(0) "" ["string:private"]=> string(0) "" ["code:protected"]=> int(0) ["file:protected"]=> string(36) "/usr/local/apache2/htdocs/client.php" ["line:protected"]=> int(73) ["trace:private"]=> array(2) {
    [0]=>
    array(4) {
      ["function"]=>
      string(6) "__call"
      ["class"]=>
      string(10) "SoapClient"
      ["type"]=>
      string(2) "->"
      ["args"]=>
      array(2) {
        [0]=>
        string(8) "findBook"
        [1]=>
        array(1) {
          [0]=>
          string(10) "0123456789"
        }
      }
    }
    [1]=>
    array(6) {
      ["file"]=>
      string(36) "/usr/local/apache2/htdocs/client.php"
      ["line"]=>
      int(73)
      ["function"]=>
      string(8) "findBook"
      ["class"]=>
      string(10) "SoapClient"
      ["type"]=>
      string(2) "->"
      ["args"]=>
      array(1) {
        [0]=>
        string(10) "0123456789"
      }
    }
} ["faultstring"]=> string(96) "Illegal argument invoking 'org.codehaus.xfire.demo.BookService.findBook(java.lang.String)': null" ["faultcode"]=> string(6) "Server" ["faultcodens"]=> string(41) "http://schemas.xmlsoap.org/soap/envelope/" } Calling __getLastRequest() gives me (slightly formatted for readability): <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns1="http://xfire.codehaus.org/BookService">
    <SOAP-ENV:Body>
        <ns1:findBook/>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope> Obviously, the required (and passed) parameter doesn't make it to the SOAP request. Is there anything I can do that will make this work? Or is it a limitation of PHP5's SoapClient? If it is a limitation, is there any other PHP SOAP client that would work with this WSDL? Thanks, Mark

« previous php.soap (#2111) next »