SOAP - некорректный XML

akxxiv

Новичок
Есть такой WSDL https://testservice.synerdocs.ru/ExchangeService.svc?singlewsdl
Я скармливаю SOAP данные, он формирует XML, на который сервис ругается. А именно н отсутствие атрибута у тега, который SOAP упорно отказывается проставлять. Возможно я какие-то настройки пропустил, или данные не той структуры передал:

Передаю данные (урезанный вариант)
PHP:
$data['Consignee']['Address']['CountryCode'] = 643;
$data['Consignee']['Address']['ForeignStreetAddress'] = 'Просвещения пр. д. 80 корп. 2';
$data['Consignee']['Inn'] = '4703058668';
$data['Consignee']['OrganizationName'] = 'ООО "О`КЕЙ"';
Предполагаю получить (вариант из примера в мануале):
XML:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <GenerateTransportWaybillConsignorTitle xmlns="http://synerdocs.ru">
            <credentials xmlns:d4p1="http://schemas.datacontract.org/2004/07/Midway.ObjectModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <d4p1:AuthToken>d6f491bd-3b1d-454a-8d4a-576bd78175d7</d4p1:AuthToken>
            </credentials>
            <request xmlns:d4p1="http://schemas.datacontract.org/2004/07/Midway.ObjectModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <d4p1:Model>
                    .......
                    <!--Данные о грузоотправителе (1 раздел ТрН), в данном случае ЮЛ-->
                    <d4p1:Consignor i:type="d4p1:LegalEntityCounterparty">
                        <!--Адрес грузоотправителя-->
                        <d4p1:Address>
                            <d4p1:CountryCode>643</d4p1:City>
                            <d4p1:ForeignStreetAddress>Просвещения пр. д. 80 корп. 2</d4p1:District>
                        </d4p1:Address>
                        <d4p1:Inn>4703058668</d4p1:Inn>
                        <d4p1:OrganizationName>ООО "О`КЕЙ"</d4p1:OrganizationName>
                    </d4p1:Consignor>
                    .....
            </request>
        </GenerateTransportWaybillConsignorTitle>
    </s:Body>
</s:Envelope>
А получаю:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:ns1="http://schemas.datacontract.org/2004/07/Midway.ObjectModel"
                   xmlns:ns2="http://synerdocs.ru">
    <SOAP-ENV:Body>
        <ns2:GenerateTransportWaybillConsignorTitle>
            <ns2:credentials>
                <ns1:AuthToken>78dcc9a9-a0b1-439f-83c2-aa7706b47cb0</ns1:AuthToken>
            </ns2:credentials>
            <ns2:request>
                <ns1:Model>
                    ....
                    <ns1:Consignor>
                        <ns1:Address>
                            <ns1:CountryCode>643</ns1:CountryCode>
                            <ns1:ForeignStreetAddress>Просвещения пр. д. 80 корп. 2</ns1:ForeignStreetAddress>
                        </ns1:Address>
                        <ns1:Inn>4703058668</ns1:Inn>
                        <ns1:OrganizationName>ООО "О`КЕЙ"</ns1:OrganizationName>
                    </ns1:Consignor>
                    ....
            </ns2:request>
        </ns2:GenerateTransportWaybillConsignorTitle>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Т.е. в ноде <ns1:Consignor> отсутствует атрибут i:type="d4p1:LegalEntityCounterparty" на что сервис и ругается. А вот как его туда прописать (если конечно не вручную XML формировать, не могу понять. Есть варианты как это сделать?
-------------
И еще один вопрос до кучи. Как правильно передавать значение типа EnumValue, дело в том, что <address> содержит в семе параметр AddressLocationType такого типа, который может иметь следующие значения https://help.synerdocs.ru/index.html?om_addresslocationtype_tip_zapisi_adresa.htm но как их передать в SOAP? Я пробовал:
PHP:
# 1. Так:
$data['Consignor']['Address']['AddressLocationType'] = 1;

# 2. И так:
$data['Consignor']['Address']['AddressLocationType'] = 'UnstructuredAddress';

# 3. И даже так:
$data['Consignor']['Address']['AddressLocationType']['UnstructuredAddress'] = 1;
Но в первых 2-х случаях сервис ругался, а в 3-м просто генерировал путой <ns1:AddressLocationType></ns1:AddressLocationType>
 

akxxiv

Новичок

Можешь сюда покопать, например.
Покопал. Грустно все. По любому приходится вникать в формат выдаваемого XML и корректировать его. Но тогда теряется смысл использования SOAP. Проще генерировать XML-ки и посылать их Curl-ом. Контроля больше.
 

akxxiv

Новичок
Ну плохо копал как-то видимо.
Видимо плохо, либо лопата кривая ((
Но хоть тресни, не могу понять как вставить именно в ноду Consignor атрибут i:type="d4p1:LegalEntityCounterparty" который в себе содержит namespace, который генерирует сам SOAP, и этот атрибут так же заранее должен быть объявлен в начале файла.
 

akxxiv

Новичок
Ну плохо копал как-то видимо.
Что-то выкопал, но чего-то не то ))

Формирую запрос так:
PHP:
$Address = [];
$Address[] = new SoapVar('643', XSD_STRING, null, null, 'CountryCode');

$AddressLocationType = [];
$AddressLocationType[] = new SoapVar('UnstructuredAddress', XSD_STRING, null, null, 'Name');
$AddressLocationType[] = new SoapVar('1', XSD_STRING, null, null, 'Code');
$Address[] = new SoapVar($AddressLocationType, SOAP_ENC_OBJECT, null, null, 'AddressLocationType');
$Address[] = new SoapVar($trn['consignee']['legal_adress'], XSD_STRING, null, null, 'ForeignStreetAddress');

$Consignee = [];
$Consignee[] = new SoapVar($Address, SOAP_ENC_OBJECT, null, null, 'Address');
$Consignee[] = new SoapVar($trn['consignee']['inn'], XSD_STRING, null, null, 'Inn');
$Consignee[] = new SoapVar($trn['consignee']['name'], XSD_STRING, null, null, 'OrganizationName');

$ns = 'http://schemas.datacontract.org/2004/07/Midway.ObjectModel';
//$ns = null;

$data['Consignee'] = new SoapVar($Consignee, SOAP_ENC_OBJECT, 'LegalEntityCounterparty',  $ns,  null,  null );
Выдает такой XML
XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:ns1="http://schemas.datacontract.org/2004/07/Midway.ObjectModel"
                   xmlns:ns2="http://synerdocs.ru" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <SOAP-ENV:Body>
        <ns2:GenerateTransportWaybillConsignorTitle>
            <ns2:credentials>
                <ns1:AuthToken>68436648-f2a1-4b80-bacd-fe90e87c013d</ns1:AuthToken>
            </ns2:credentials>
            <ns2:request>
                <ns1:Model>
                    <ns1:Consignee xsi:type="ns1:LegalEntityCounterparty">
                        <ns1:Inn xsi:nil="true"></ns1:Inn>
                        <ns1:OrganizationName xsi:nil="true"></ns1:OrganizationName>
                    </ns1:Consignee>
                </ns1:Model>
                <ns1:Options>
                    <ns1:ValidateContent>true</ns1:ValidateContent>
                </ns1:Options>
            </ns2:request>
        </ns2:GenerateTransportWaybillConsignorTitle>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Т.Е. отбросил Адрес и обнулил Inn и OrganizationName, хотя если убрать LegalEntityCounterparty или не поставить $ns, то структура корректная, но ругается Сервис.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:ns1="http://schemas.datacontract.org/2004/07/Midway.ObjectModel"
                   xmlns:ns2="http://synerdocs.ru">
<SOAP-ENV:Body>
    <ns2:GenerateTransportWaybillConsignorTitle>
        <ns2:credentials>
            <ns1:AuthToken>0b9bbd20-4775-430b-bd65-da0293bd8565</ns1:AuthToken>
        </ns2:credentials>
        <ns2:request>
            <ns1:Model>
                <ns1:Consignee>
                    <Address>
                        <CountryCode>643</CountryCode>
                        <AddressLocationType>
                            <Name>UnstructuredAddress</Name>
                            <Code>1</Code>
                        </AddressLocationType>
                        <ForeignStreetAddress>390020, г.Рязань, ул.Коняева, д.117. Лит. А, пом. Н2.
                        </ForeignStreetAddress>
                    </Address>
                    <Inn>6213010269</Inn>
                    <OrganizationName>ООО «Океан»</OrganizationName>
                </ns1:Consignee>
            </ns1:Model>
            <ns1:Options>
                <ns1:ValidateContent>true</ns1:ValidateContent>
            </ns1:Options>
        </ns2:request>
    </ns2:GenerateTransportWaybillConsignorTitle>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Почти сдался ((
 

akxxiv

Новичок
я не пробывал, первое в гугле нашел, оно должно необходимые классы создать

все твои new SoapVar это не правильный подход, это делает SoapClient сам. тебе только вызовы писать нужно
Воспользовался вашим советом. Нагенерировал больше 1000 файлов, переписал запрос все с использованием классов, но результат тот-же - все падает на том же месте. А именно:

PHP:
$Consignor = new \StructType\LegalEntityCounterparty(
   $trn['shipper']['inn'],
   $trn['shipper']['kpp'],
   $trn['shipper']['name']
);
выдает XML

XML:
<ns1:Consignor>
    <ns1:AdditionalInfoForParticipants xsi:nil="true"></ns1:AdditionalInfoForParticipants>
    <ns1:Address></ns1:Address>
    <ns1:BankAccount xsi:nil="true"></ns1:BankAccount>
    <ns1:Contact xsi:nil="true"></ns1:Contact>
    <ns1:DepartmentName xsi:nil="true"></ns1:DepartmentName>
    <ns1:Okpo xsi:nil="true"></ns1:Okpo>
</ns1:Consignor>
Т.е. он проигнорировал, что ему был передан объект LegalEntityCounterparty, а не CounterpartyBase, и вставил значения от родительского класса ( LegalEntityCounterparty extends CounterpartyBase ), ну и соответсвенно ни какого атрибута i:type="d4p1:LegalEntityCounterparty" в ноде <ns1:Consignor> нет.

Возможно я снова упустил какие-то детали...
 

WMix

герр M:)ller
Партнер клуба
ошибку все-равно искать тебе, возможно где-то аннотация поможет, возможно кастинг, на край пользуй встроеные функции типа SoapVar. важно понимать что сервис просит тогда проще подстраиваться. мне если честно лень разбираться
 
Сверху