Использование WSDL с абстрактными типами в PHP - PullRequest
4 голосов
/ 27 августа 2009

Я работаю над интеграцией нашего веб-приложения с Microsoft Exchange 2007. Я использую веб-службы Exchange (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"/>

Не может ли обработка SOAP в PHP правильно обрабатывать абстрактные типы в WSDL, или же что-то не так с самим WSDL? WSDL хранится локально, поэтому я могу внести в него изменения, если возникнет такая необходимость.

Заранее благодарю за помощь.

Edit:
Я просто хотел уточнить, что я сам не формирую XML. Я использую следующий код, который должен создавать правильный XML:

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

Ответы [ 3 ]

2 голосов
/ 27 августа 2009

Я нашел ответ на свой вопрос. Очевидно, объект 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 голос
/ 28 августа 2009

Вы можете использовать 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 (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

1 голос
/ 27 августа 2009

У меня очень похожая проблема при попытке добавить дополнительные свойства с элементом FieldURI. PHP SoapClient создает XML как:

<Path FieldURI='folder:DisplayName'>

когда оно должно быть создано как:

<FieldURI FieldURI='folder:DisplayName'>

В качестве примечания я использовал wsdl2php для создания прокси-классов в попытке решить проблему, но это не помогло. Поэтому теперь мне интересно, является ли обмен WSDL возвратом неправильным, если SoapClient php содержит ошибки или если wsdl2php создал неправильные прокси-классы. Если у кого-то есть понимание этой проблемы, пожалуйста, сообщите нам.

...