Reputation: 1373
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. However, I am running into some issues with the WSDL. There are several types defined in the WSDL that have elements of abstract types. For example:
<xs:complexType name="RestrictionType">
<xs:sequence>
<xs:element ref="t:SearchExpression"/>
</xs:sequence>
</xs:complexType>
SearchExpression is an abtract type. There are several types that extend SearchExpression such as 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:
<Restriction>
<Exists>
...
</Exists>
</Restriction>
However, when I attempt to make the call using PHP's SoapClient class I receive the following error:
The request failed schema validation: The element 'http://schemas.microsoft.com/exchange/services/2006/types:SearchExpression' is abstract or its type is abstract.
If I modify the definition of the RestrictionType type to the follow, the call works:
<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? The WSDL is stored locally so I can make edits to it if the need arrises.
Thank you for your help in advance.
Edit:
I just wanted to clarify that I am not forming the XML myself. I am using the following code that should be creating the proper XML:
$request->Restriction->IsGreaterThan->FieldURI->FieldURI =
'item:DateTimeReceived';
$request->Restriction->IsGreaterThan->FieldURIOrConstant
->Constant->Value = date('c', $last_checked_time);
Upvotes: 4
Views: 6185
Reputation: 11
I'm having a very similar problem trying to add additional properties with the FieldURI element. PHP's SoapClient is creating the XML as:
<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. 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. If anyone has any insight into this issue, please let us know.
Upvotes: 1
Reputation: 39
You can use substitutionGroup only with global elements not with types. The same with
<xs:element ref="t:SearchExpression"/>
if you use a ref reference you need a element and not a type!
<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.
<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
Upvotes: 1
Reputation: 1373
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. To combat the issue, I edited the WSDL and replaced references to any abstract types with references to the concrete types that extend them. So for the RestrictionType example above, I changed the schema definition to match the following:
<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.
Upvotes: 3