我遇到了几个不同的WSDL文件,其中包含一个元素和一个具有相同名称的complexType。例如,http://soap.search.msn.com/webservices.asmx?wsdl有两个名为“SearchResponse”的实体:
在这种情况下,我无法弄清楚如何使用SoapClient()“classmaps”选项将那些实体正确映射到PHP类。
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 Services通过允许您为“Element”或“ComplexType”实体指定自定义后缀来处理此问题。
http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html#wp149350
所以,现在我感觉无法用PHP的SoapClient来做到这一点,但是我很好奇是否有人可以提供任何建议。 FWIW,我无法编辑远程WDSL。
有任何想法吗???
最佳答案
这是我的主意,但我认为您可以将两种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')));
关于php - 将PHP SoapClient classmap选项与WSDL一起使用,其中WSDL包含具有相同名称的元素和complexType,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3784161/