简体   繁体   English

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

[英]Using a WSDL with abstract types in PHP

I'm working on an integration between our web application and Microsoft Exchange 2007. I am using Exchange Web Services (EWS) to communicate to the Exchange Server. 我正在开发Web应用程序和Microsoft Exchange 2007之间的集成。我正在使用Exchange Web服务(EWS)与Exchange Server进行通信。 However, I am running into some issues with the WSDL. 但是,我遇到了WSDL的一些问题。 There are several types defined in the WSDL that have elements of abstract types. WSDL中定义了几种具有抽象类型元素的类型。 For example: 例如:

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

SearchExpression is an abtract type. SearchExpression是一种abtract类型。 There are several types that extend SearchExpression such as ExistsType: 有几种类型可以扩展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"/>

I would expect to be able to make a valid call that produces the following XML: 我希望能够进行产生以下XML的有效调用:

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

However, when I attempt to make the call using PHP's SoapClient class I receive the following error: 但是,当我尝试使用PHP的SoapClient类进行调用时,我收到以下错误:

The request failed schema validation: The element ' http://schemas.microsoft.com/exchange/services/2006/types:SearchExpression ' is abstract or its type is abstract. 请求失败的架构验证:元素' http://schemas.microsoft.com/exchange/services/2006/types:SearchExpression '是抽象的或其类型是抽象的。

If I modify the definition of the RestrictionType type to the follow, the call works: 如果我将RestrictionType类型的定义修改为以下,则调用有效:

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

Is PHP's SOAP handling not able to properly handle abstract types in the WSDL, or could there be something wrong with the WSDL itself? PHP的SOAP处理是否无法正确处理WSDL中的抽象类型,或者WSDL本身是否存在问题? The WSDL is stored locally so I can make edits to it if the need arrises. WSDL存​​储在本地,因此如果需要,我可以对其进行编辑。

Thank you for your help in advance. 提前谢谢你的帮助。

Edit: 编辑:
I just wanted to clarify that I am not forming the XML myself. 我只想澄清一点,我自己并没有形成XML。 I am using the following code that should be creating the proper XML: 我正在使用以下代码来创建正确的XML:

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

I found the answer to my own question. 我找到了自己问题的答案。 Apparently PHP's SOAP object cannot properly form XML from the object structure I am using when there are abstract types. 显然,当有抽象类型时,PHP的SOAP对象无法从我正在使用的对象结构中正确地形成XML。 To combat the issue, I edited the WSDL and replaced references to any abstract types with references to the concrete types that extend them. 为了解决这个问题,我编辑了WSDL并将对任何抽象类型的引用替换为对扩展它们的具体类型的引用。 So for the RestrictionType example above, I changed the schema definition to match the following: 因此,对于上面的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>

I hope this helps somebody else out. 我希望这有助于其他人。 Thanks to all who took the time to at least read my post. 感谢所有花时间至少阅读我的帖子的人。

I'm having a very similar problem trying to add additional properties with the FieldURI element. 我尝试使用FieldURI元素添加其他属性时遇到了类似的问题。 PHP's SoapClient is creating the XML as: PHP的SoapClient正在创建XML:

<Path FieldURI='folder:DisplayName'>

when it should be creating it as: 什么时候应该创建它:

<FieldURI FieldURI='folder:DisplayName'>

As a side note, I used wsdl2php to create proxy classes in an attempt to fix the problem, but it did not help. 作为旁注,我使用wsdl2php来创建代理类以尝试解决问题,但它没有帮助。 So I'm now wondering if the WSDL exchange returns is wrong, if php's SoapClient is buggy, or if wsdl2php created incorrect proxy classes. 所以我现在想知道WSDL交换返回是否错误,如果php的SoapClient是错误的,或者wsdl2php是否创建了错误的代理类。 If anyone has any insight into this issue, please let us know. 如果有人对此问题有任何见解,请告诉我们。

You can use substitutionGroup only with global elements not with types. 您只能将substitutionGroup与不具有类型的全局元素一起使用。 The same with 同样的

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

if you use a ref reference you need a element and not a type! 如果你使用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"/>

A other approache is just to use abstract types and XMLSchema-instance (xsi:type) instead and leave the substitutionGroup as you did. 另一个方法就是使用抽象类型和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">

This may explain that a bit better as i did. 这可能解释了我做得更好一些。 http://www.xfront.com/ExtensibleContentModels.pdf http://www.xfront.com/ExtensibleContentModels.pdf

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM