在PHP中使用带有抽象类型的WSDL

时间:2009-08-27 13:32:31

标签: php web-services soap wsdl

我正在开发Web应用程序和Microsoft Exchange 2007之间的集成。我正在使用Exchange Web服务(EWS)与Exchange Server进行通信。但是,我遇到了WSDL的一些问题。 WSDL中定义了几种具有抽象类型元素的类型。例如:

<xs:complexType name="RestrictionType">
  <xs:sequence>
    <xs:element ref="t:SearchExpression"/>
  </xs:sequence>
</xs:complexType>

SearchExpression是一种abtract类型。有几种类型可以扩展SearchExpression,例如ExistsType:

<xs:complexType name="ExistsType"> 
  <xs:complexContent> 
    <xs:extension base="t:SearchExpressionType"> 
      ...
    </xs:extension>
  </xs:complexContent>
</xs:complexType>
<xs:element name="Exists" type="t:ExistsType" substitutionGroup="t:SearchExpression"/>

我希望能够进行产生以下XML的有效调用:

<Restriction>
  <Exists>
    ...
  </Exists>
</Restriction>

但是,当我尝试使用PHP的SoapClient类进行调用时,收到以下错误:

  

请求模式验证失败:元素“http://schemas.microsoft.com/exchange/services/2006/types:SearchExpression”是抽象的或其类型是抽象的。

如果我将RestrictionType类型的定义修改为以下内容,则调用有效:

<xs:element name="Exists" type="t:ExistsType"/>

PHP的SOAP处理是否无法正确处理WSDL中的抽象类型,或者WSDL本身是否存在问题? WSDL存​​储在本地,因此如果需要,我可以对其进行编辑。

提前感谢您的帮助。

修改
我只想澄清一点,我自己并没有形成XML。我正在使用以下代码来创建正确的XML:

$request->Restriction->IsGreaterThan->FieldURI->FieldURI =
  'item:DateTimeReceived';
$request->Restriction->IsGreaterThan->FieldURIOrConstant
  ->Constant->Value = date('c', $last_checked_time);

3 个答案:

答案 0 :(得分:2)

我找到了自己问题的答案。显然,当有抽象类型时,PHP的SOAP对象无法从我正在使用的对象结构中正确地形成XML。为了解决这个问题,我编辑了WSDL并将对任何抽象类型的引用替换为对扩展它们的具体类型的引用。因此,对于上面的RestrictionType示例,我更改了架构定义以匹配以下内容:

<xs:complexType name="RestrictionType"> 
  <xs:choice maxOccurs ="unbounded">
    <xs:element ref="t:Exists"/>
    <xs:element ref="t:Excludes"/>
    <xs:element ref="t:IsEqualTo"/>
    <xs:element ref="t:IsNotEqualTo"/>
    <xs:element ref="t:IsGreaterThan"/>
    <xs:element ref="t:IsGreaterThanOrEqualTo"/>
    <xs:element ref="t:IsLessThan"/>
    <xs:element ref="t:IsLessThanOrEqualTo"/>
    <xs:element ref="t:Not"/>
    <xs:element ref="t:And"/>
    <xs:element ref="t:Or"/>
  </xs:choice>
</xs:complexType>

我希望这有助于其他人。感谢所有花时间至少阅读我的帖子的人。

答案 1 :(得分:1)

我在尝试使用FieldURI元素添加其他属性时遇到了类似的问题。 PHP的SoapClient正在创建XML:

<Path FieldURI='folder:DisplayName'>

什么时候应该创建它:

<FieldURI FieldURI='folder:DisplayName'>

作为旁注,我使用 wsdl2php 来创建代理类以尝试解决问题,但它没有帮助。所以我现在想知道WSDL交换返回是否错误,如果php的SoapClient是错误的,或者 wsdl2php 创建了错误的代理类。如果有人对此问题有任何见解,请告诉我们。

答案 2 :(得分:1)

您只能将 substitutionGroup 与不具有类型的全局元素一起使用。 与

相同
<xs:element ref="t:SearchExpression"/>

如果你使用 ref 引用,你需要一个元素而不是一个类型!

<xsd:complexType name="PublicationType"/>
<xsd:element name="Publication" abstract="true" type="PublicationType"/>

<xsd:element name="Book" substitutionGroup="Publication" type="BookType"/>
<xsd:element name="Magazine" substitutionGroup="Publication"  type="MagazineType"/>

另一个方法就是使用抽象类型和XMLSchema-instance(xsi:type),然后保留 substitutionGroup

<xsd:complexType name="PublicationType" abstract="true"/>
<xsd:element name="Publication" type="PublicationType"/>

<xsd:element name="Book"type="BookType"/>
<xsd:element name="Magazine" type="MagazineType"/>

<Publication" xsi:type="MagazineType">

这可能解释了我做得更好一些。 http://www.xfront.com/ExtensibleContentModels.pdf