【问题标题】:Using a WSDL with abstract types in PHP在 PHP 中使用带有抽象类型的 WSDL
【发布时间】:2009-08-27 13:32:30
【问题描述】:

我正在处理我们的 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 是一种抽象类型。有几种扩展 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);

【问题讨论】:

    标签: php web-services soap wsdl


    【解决方案1】:

    我找到了自己问题的答案。显然,当存在抽象类型时,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>
    

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

    【讨论】:

    • 我也让 SoapVar 工作了,看看:$var = new SoapVar($data, SOAP_ENC_ARRAY, 'RestrictionType', 'http://thenamespace/webservice/namespace')
    【解决方案2】:

    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

    【讨论】:

    • @RedAssBaboon 你的解释很有道理,但这需要我自己形成 XML。
    • 如果你的意思是“自己形成 XML”,你需要修改你的 XML 模式,你是对的。但是,当您使用 PHP Soap 扩展时。如果您使用 classmap 选项,PHP 的 SoapClient/Server 类将为您执行此操作! de2.php.net/manual/de/soapclient.soapclient.php
    【解决方案3】:

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

    <Path FieldURI='folder:DisplayName'>
    

    什么时候应该创建它:

    <FieldURI FieldURI='folder:DisplayName'>
    

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

    【讨论】:

    • @Jake 我也遇到了这个问题。我能够使用下面的解决方案将 types.xsd 中对 Path 的任何引用替换为扩展它的类型。我一直在开发一个库,以便在我进行当前项目时更轻松地使用 Exchange,并且我已经将我的解决方案添加到库中。您可能想看看它是否对您有用:code.google.com/p/php-ews
    • 谢谢哥们。几天前我实际上偶然发现了你的图书馆,但现在才意识到你是作者。我决定不使用您的库,因为我无法判断它处于何种完成状态,并且我正在考虑做一些稍微不同的事情。但是,如果您正在积极研究它,那么我们合作可能是有意义的。 -杰克莱维特
    • 如果您对合作有诚意,请随时通过上述项目的链接与我联系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 2011-01-22
    • 1970-01-01
    相关资源
    最近更新 更多