14

我遇到了一些不同的 WSDL 文件,它们包含同名的元素和 complexType。例如,http ://soap.search.msn.com/webservices.asmx?wsdl 有两个名为“SearchResponse”的实体:

在这种情况下,我无法弄清楚如何使用 SoapClient()“classmaps”选项将这些实体正确映射到 PHP 类。

PHP手册是这样说的:

classmap 选项可用于将某些 WSDL 类型映射到 PHP 类。此选项必须是一个数组,其中 WSDL 类型作为键,PHP 类的名称作为值。

不幸的是,由于有两个具有相同键('SearchResponse')的 WSDL 类型,我无法弄清楚如何区分这两个 SearchResponse 实体并将它们分配给它们相应的 PHP 类。

例如,下面是示例 WSDL 的相关片段:

<xsd:complexType name="SearchResponse">
    <xsd:sequence>
        <xsd:element minOccurs="1" maxOccurs="1" name="Responses" type="tns:ArrayOfSourceResponseResponses"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:element name="SearchResponse">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element minOccurs="1" maxOccurs="1" name="Response" type="tns:SearchResponse"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

这是显然无法工作的 PHP,因为类映射键是相同的:

<?php $server = new SoapClient("http://soap.search.msn.com/webservices.asmx?wsdl", array('classmap' => array('SearchResponse' => 'MySearchResponseElement', 'SearchResponse' => 'MySearchResponseComplexType'))); ?>

在寻找解决方案时,我发现 Java Web 服务通过允许您为“Element”或“ComplexType”实体指定自定义后缀来处理此问题。

http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html#wp149350

所以,现在我觉得 PHP 的 SoapClient 没有办法做到这一点,但我很好奇是否有人可以提供任何建议。FWIW,我无法编辑远程 WDSL。

有任何想法吗???

4

1 回答 1

7

这不是我的想法,但我认为您可以将两种 SearchResponse 类型都映射到 MY_SearchResponse 并尝试抽象出两者之间的区别。这很笨拙,但也许像这样?

<?php
//Assuming SearchResponse<complexType> contains SearchReponse<element> which contains and Array of SourceResponses
//You could try abstracting the nested Hierarchy like so:
class MY_SearchResponse
{
   protected $Responses;
   protected $Response;

   /**
    * This should return the nested SearchReponse<element> as a MY_SearchRepsonse or NULL
    **/
   public function get_search_response()
   {
      if($this->Response && isset($this->Response))
      {
         return $this->Response; //This should also be a MY_SearchResponse
      }
      return NULL;
   }

   /**
    * This should return an array of SourceList Responses or NULL
    **/
   public function get_source_responses()
   {
      //If this is an instance of the top SearchResponse<complexType>, try to get the SearchResponse<element> and it's source responses
      if($this->get_search_response() && isset($this->get_search_response()->get_source_responses()))
      {
         return $this->get_search_response()->get_source_responses();
      }
      //We are already the nested SearchReponse<element> just go directly at the Responses
      elseif($this->Responses && is_array($this->Responses)
      {
         return $this->Responses;
      }
      return NULL;
   }
}

class MY_SourceResponse
{
  //whatever properties SourceResponses have
}

$client = new SoapClient("http:/theurl.asmx?wsdl", array('classmap' => array('SearchResponse' => 'MY_SearchResponse', 'SourceResponse' => 'MY_SourceResponse')));
于 2010-10-08T16:11:11.170 回答