Я пытаюсь разобрать файл WSDL для создания классов PHP. Хотя для этого существует множество инструментов, все они в настоящее время не в состоянии документировать доступные SOAPHeaders и SOAPFaults, которые существуют для запроса и / или ответа.
У меня достаточно понимания, чтобы построить это:https://github.com/rquadling/wsdl2php. Но затем я сталкиваюсь с сервисом, который не соответствует моим предыдущим знаниям.
Итак. Пример WSDL-файла (используется только как метод входа в систему и некоторые операции импорта).
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns:tns="urn:platform_2012_2.webservices.netsuite.com"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:platformMsgs="urn:messages_2012_2.platform.webservices.netsuite.com"
xmlns:platformFaults="urn:faults_2012_2.platform.webservices.netsuite.com"
targetNamespace="urn:platform_2012_2.webservices.netsuite.com">
<types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xsd:import namespace="urn:core_2012_2.platform.webservices.netsuite.com" schemaLocation="https://webservices.eu2.netsuite.com/xsd/platform/v2012_2_0/core.xsd"/>
<xsd:import namespace="urn:faults_2012_2.platform.webservices.netsuite.com" schemaLocation="https://webservices.eu2.netsuite.com/xsd/platform/v2012_2_0/faults.xsd"/>
<xsd:import namespace="urn:messages_2012_2.platform.webservices.netsuite.com" schemaLocation="https://webservices.eu2.netsuite.com/xsd/platform/v2012_2_0/messages.xsd"/>
<xsd:import namespace="urn:common_2012_2.platform.webservices.netsuite.com" schemaLocation="https://webservices.eu2.netsuite.com/xsd/platform/v2012_2_0/common.xsd"/>
<!-- snip -->
</xsd:schema>
</types>
<message name="headers">
<part name="applicationInfo" element="platformMsgs:applicationInfo"/>
<part name="partnerInfo" element="platformMsgs:partnerInfo"/>
<part name="documentInfo" element="platformMsgs:documentInfo"/>
<part name="preferences" element="platformMsgs:preferences"/>
<part name="searchPreferences" element="platformMsgs:searchPreferences"/>
<part name="passport" element="platformMsgs:passport"/>
</message>
<message name="loginRequest">
<part name="parameters" element="platformMsgs:login"/>
</message>
<message name="loginResponse">
<part name="parameters" element="platformMsgs:loginResponse"/>
</message>
<!-- snip -->
<portType name="NetSuitePortType">
<operation name="login">
<input name="loginRequest" message="tns:loginRequest"/>
<output name="loginResponse" message="tns:loginResponse"/>
<fault name="InsufficientPermissionFault" message="tns:InsufficientPermissionFault"/>
<fault name="InvalidAccountFault" message="tns:InvalidAccountFault"/>
<fault name="InvalidCredentialsFault" message="tns:InvalidCredentialsFault"/>
<fault name="InvalidVersionFault" message="tns:InvalidVersionFault"/>
<fault name="ExceededRequestLimitFault" message="tns:ExceededRequestLimitFault"/>
<fault name="UnexpectedErrorFault" message="tns:UnexpectedErrorFault"/>
</operation>
<!-- snip -->
</portType>
<binding name="NetSuiteBinding" type="tns:NetSuitePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="login">
<soap:operation soapAction="login"/>
<input name="loginRequest">
<soap:header message="tns:headers" part="applicationInfo" use="literal"/>
<soap:header message="tns:headers" part="partnerInfo" use="literal"/>
<soap:body use="literal"/>
</input>
<output name="loginResponse">
<soap:body use="literal"/>
</output>
<fault name="InsufficientPermissionFault">
<soap:fault name="InsufficientPermissionFault" use="literal"/>
</fault>
<fault name="InvalidAccountFault">
<soap:fault name="InvalidAccountFault" use="literal"/>
</fault>
<fault name="InvalidCredentialsFault">
<soap:fault name="InvalidCredentialsFault" use="literal"/>
</fault>
<fault name="InvalidVersionFault">
<soap:fault name="InvalidVersionFault" use="literal"/>
</fault>
<fault name="ExceededRequestLimitFault">
<soap:fault name="ExceededRequestLimitFault" use="literal"/>
</fault>
<fault name="UnexpectedErrorFault">
<soap:fault name="UnexpectedErrorFault" use="literal"/>
</fault>
</operation>
<!-- snip -->
</binding>
<service name="NetSuiteService">
<port name="NetSuitePort" binding="tns:NetSuiteBinding">
<soap:address location="https://webservices.eu2.netsuite.com/services/NetSuitePort_2012_2"/>
</port>
</service>
</definitions>
Я использую XPath для извлечения заголовков (вход и выход) и ошибок ...
$xPathMaster['Headers'] = [
'headers_in' => [
'Definitions/Binding/Operation[method]/Input/Header' => '//*[local-name()="definitions"]/*[local-name()="binding"]/*[local-name()="operation"][@name="'.$call.'"]/*[local-name()="input"]/*[local-name()="header"]/@part',
],
'headers_out' => [
'Definitions/Binding/Operation[method]/Output/Header' => '//*[local-name()="definitions"]/*[local-name()="binding"]/*[local-name()="operation"][@name="'.$call.'"]/*[local-name()="output"]/*[local-name()="header"]/@part',
],
'faults' => [
'Definitions/Binding/Operation[method]/fault' => '//*[local-name()="definitions"]/*[local-name()="binding"]/*[local-name()="operation"][@name="'.$call.'"]/*[local-name()="fault"]/@name',
],
];
($call
- это имя вызываемого метода).
Так что мой инструмент знает, что заголовок applicationInfo
связан с loginResponse
.
ЧтоЯ не уверен, как это сделать, программно найти структуру для этого типа.
Вручную, я знаю, что она существует как сопоставленный тип в импорте пространства имен сообщений из https://webservices.eu2.netsuite.com/xsd/platform/v2012_2_0/messages.xsd ...
<!-- snip -->
<complexType name="ApplicationInfo">
<sequence>
<element name="applicationId" minOccurs="0" type="xsd:string"/>
</sequence>
</complexType>
<element name="applicationInfo" type="platformMsgs:ApplicationInfo"/>
Я использую PHP-технологию SOAP, и она может дать мне список типов ($client->__getTypes()
, но это показывает структуру как ...
struct ApplicationInfo {
string applicationId;
}
(поэтому он должен выполнить импорт изнутри), но без упоминания applicationInfo
.
Так что, пытаясь сделать это через PHP DOM, используя запросы XPath, и я теряюсь, как «расширить» импорт такфактический контент присутствует, а не ссылка.
Я вроде как потерян.