2009-08-25 2 views
6

Я не могу понять, как установить атрибут для запроса SOAP без использования кодировки XSD_ANYXML.SOAP-запрос с атрибутом

Параметр запроса должен выглядеть следующим образом

<request 
    xmlns:ns="/some/ns"> 
    ... 
     <ns:parameter attr="some attribute"> 
      value 
     </ns:parameter> 
    ... 
</request> 

Конечно следующий код работает, но это довольно уродливые (некрасиво, потому что он использует конкатенацию, где он должен использовать SOAP_Client API и потому, что он делает не использовать общее пространство имен)

$param = new SoapVar(
    '<ns_xxx:parameter xmlns:ns_xxx="/some/ns" attr="some attribute"> 
     value 
    </ns_xxx:parameter>', 
    XSD_ANYXML 
); 

есть ли лучший способ создать параметр запроса SOAP с пространством имен и атрибутов?

Я ищу с.th. как следующий (это лишь некоторые псевдо-код, используя SoapVar API):

$param = new SoapVar(
    array(
     '_' => 'value', 
     'attr' => 'some attribute' 
    ), 
    SOME_ENCODING, 
    null, 
    null, 
    null, 
    '/some/ns' 
); 
+0

Я не так хорошо разбираюсь в SOAP, каким хочу быть, но поддерживает ли он запросы с атрибутами? (Я знаю, что WSDL имеет атрибуты, но как он обрабатывает атрибуты в отправленном XML?) Создаете ли вы службу или уже настроены? Если это ваш сервис, я бы отбросил часть атрибута и переместил его в свой собственный элемент внутри параметра. Может быть, как элемент без значения, например '' – Anthony

+0

@Anthony: я, к сожалению, не контролирую SOAP-сервер и не влияю на определение сервиса (иначе, конечно, я мог бы просто сделать атрибут элементом –

ответ

0

SOAP не поддерживает атрибуты, может быть, вы должны использовать REST вместо этого!

EDIT: Пожалуйста, проверьте w3c Тип кузова: «4.3 SOAP Body» и помните, что вам необходимо закодировать ваше сообщение с «мыльным конвертом» именами и описать ваших типов XML вот почему, вы можете» t использовать атрибуты для описания ваших данных сообщений.

Но если вы спросите меня, это станет возможным! Вы можете использовать пользовательский парсер SoapClient или что-то в этом роде и конвертировать ваше сообщение по своему усмотрению. Примером этого может быть RSS по SOAP http://www.ibm.com/developerworks/webservices/library/ws-soaprdf. Но проблема в том, что вам не хватало описательной информации о ваших данных/типах сообщений, а другие клиенты не могли легко понять ваши сообщения!

Моей лучшей практикой для вас было бы использовать элементы вместо атрибутов, Я знаю, что вам нужно исправить вашу XML-схему, но это так, как это происходит, или переключиться на другую технологию.

+1

Я понимаю, что вы любите REST над SOAP, но этот ответ действительно не помогает вообще. Он не помогает людям говорить, а не использовать технологию, когда они пытаются решить проблему в этой конкретной технологии. вы пишете неправильно: SOAP поддерживает атрибуты. cf http: //www.w3.org/TR/2000/NOTE-SOAP-20000508/# _ Toc478383492 –

+0

Нет, я предпочитаю SOAP over REST. Я разрабатываю веб-службы SOAP и PHP уже пару лет. Я немного изменил свой ответ, надеюсь, это поможет. – RedAssBaboon

+0

Ответ RAB технически корректен. Проблема в том, что некоторые разработчики потребуют передачи данных в атрибутах в любом случае. Реализация PHP SoapVar, с другой стороны, следует букве закона и не помогает с такими атрибутами, как обычная библиотека XML. – method

-3

SOAP 1 поддерживает атрибуты. Ниже приведен пример кода Perl с использованием как атрибуты и значения (от клиента):

$som = $client->call(
    'tran:getContent', 
    SOAP::Header->name('cred:credentials')->attr({ 
     'username' => $username, 
     'password' => 'xxx', 
     'customerID' => 'xxx'} 
    ), 
    SOAP::Data->name('contentID')->value('9999') 
) 
+2

Жаль, что вопрос был о PHP, а не Prel. –

3

Для этого вам необходимо полученный класс от SoapClient и переопределить метод __doRequest():

class ABRSoapClient extends SoapClient { 

    // return xml request 
    function __doRequest($request, $location, $action, $version) { 
     $dom = new DOMDocument('1.0', 'UTF-8'); 
     $dom->preserveWhiteSpace = false; 
     $xml= $dom->loadXML($request); 
     // Goto request Node and Set the attribute 
     $attr_ns = $dom->createAttributeNS('xmlns:ns', ''); // instead of xmlns:ns use Namespace URL 
     $attr_ns->value = '/some/ns'; 
     // add atribute in businessReport node 
     $dom->getElementsByTagName($report_type)->item(0)->appendChild($attr_ns); 
     $request = $dom->saveXML(); 
     return parent::__doRequest($request, $location, $action, $version); 
    } 
} 

$client = new ABRSoapClient(.....); 
$save_result = $client->request($param); 

// You can check the form request using function 
$client->__getLastRequest(); 

Надеюсь, это решит вашу проблему.

+0

Я не знал, как настроить функцию __doRequest, но у меня была эта одна строка кода, и она работала: // Замените пространство имен на все известные типы $ request = str_replace ('RequestBase', 'ns1: RequestBase ', $ request); return parent :: __ doRequest ($ request, $ location, $ action, $ version); –

Смежные вопросы