2009-08-25 15 views
6

Nie mogę się dowiedzieć, jak ustawić atrybut dla żądania SOAP bez korzystania z kodowania XSD_ANYXML.Żądanie SOAP z atrybutem

Parametr wniosek powinien wyglądać następująco

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

Oczywiście poniższy kod działa, ale jest to raczej brzydki (brzydkie, ponieważ wykorzystuje ciąg konkatenacji gdzie powinien korzystania z SOAP_Client API a ponieważ robi nie należy stosować ogólne nazw)

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

Czy istnieje lepszy sposób, aby utworzyć parametr żądania mydło z nazw i atrybut?

Szukam s.th. jak poniżej (jest to tylko niektóre pseudo kod używając SoapVar API):

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

Nie jestem tak dobrze zorientowany w SOAP, jak chcę, ale czy obsługuje on żądania z atrybutami? (Wiem, że WSDL ma atrybuty, ale jak przetwarza atrybuty w XML wysłanym do niego?) Czy tworzysz usługę, czy jest już skonfigurowana? Jeśli to twoja usługa, upuszczę część atrybutu i przeniesię ją do jej własnego elementu w parametrze. Może jako element bez wartości, np. '' – Anthony

+0

@Anthony: niestety nie kontroluję serwera SOAP i nie mam wpływu na definicję usługi (w przeciwnym razie mógłbym po prostu uczynić atrybut elementem –

Odpowiedz

0

SOAP nie obsługuje atrybuty mogą być należy użyć zamiast odpoczywać!

EDIT: Proszę sprawdzić W3C Budowa ciała „4,3 SOAP Body” i pamiętać, że trzeba zakodować wiadomość z „mydła kopercie” nazw i opisać swoje typy XML to dlaczego, można” • używać atrybutów do opisu danych wiadomości.

Ale jeśli mnie zapytasz, będzie to możliwe! Możesz użyć niestandardowego parsera SoapClient lub czegoś podobnego i przekonwertować wiadomość tak, jak Ci się podoba. Przykładem może być RSS przez SOAP http://www.ibm.com/developerworks/webservices/library/ws-soaprdf. Ale problem polegałby na tym, że pominęłbyś opisowe informacje o twoich danych/typach wiadomości, a inni klienci nie mogliby łatwo zrozumieć twoich wiadomości!

Moja najlepsza praktyka polegałaby na używaniu elementów zamiast atrybutów, Wiem, że musisz naprawić swój schemat XML, ale tak to wygląda lub przejść do innej technologii.

+1

Rozumiem twoje upodobanie do REST przez SOAP, ale ta odpowiedź naprawdę nie pomaga wcale, nie pomaga ludziom, nie korzysta z technologii, kiedy próbują rozwiązać problem w tej konkretnej technologii. piszesz jest simlpy źle: SOAP obsługuje atrybuty. cf http: //www.w3.org/TR/2000/NOTE-SOAP-20000508/# _ Toc478383492 –

+0

Nie preferuję SOAP przez REST. Zajmuję się tworzeniem serwisów SOAP i PHP od kilku lat. Trochę zmodyfikowałem swoją odpowiedź, mam nadzieję, że to pomoże. – RedAssBaboon

+0

Odpowiedź RAB jest poprawna pod względem technicznym. Problem polega na tym, że niektórzy realizatorzy i tak będą wymagać przekazywania danych w atrybutach. Z drugiej strony implementacja SoapVar w PHP jest zgodna z literą prawa i nie pomaga z atrybutami takimi jak zwykła biblioteka XML. – method

-3

SOAP 1 obsługuje atrybuty. Oto przykład kodu Perl przy użyciu obu atrybutów i wartości (od klienta):

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

Szkoda, że ​​pytanie dotyczyło PHP, a nie Prel. –

3

Do tego trzeba pochodzić klasę z SoapClient i zastąpić __doRequest metoda():

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(); 

Mam nadzieję, że rozwiąże to Twój problem.

+0

Nie wiedziałem, jak dostosować funkcję __doRequest, ale miałem w niej jedną linię kodu i działało: // Zastępcza przestrzeń nazw dla wszystkich znanych typów $ request = str_replace ('RequestBase', 'ns1: RequestBase ', $ request); return parent :: __ doRequest ($ request, $ location, $ action, $ version); –

Powiązane problemy