2009-08-25 47 views
6

Tôi không thể tìm ra cách đặt thuộc tính thành yêu cầu SOAP mà không sử dụng mã hóa XSD_ANYXML.Yêu cầu SOAP với thuộc tính

Các tham số yêu cầu nên xem xét như sau

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

Tất nhiên đoạn mã sau hoạt động, nhưng nó khá xấu xí (xấu xí, vì nó sử dụng nối chuỗi mà nó nên sử dụng API SOAP_Client và bởi vì nó không sử dụng không gian tên chung)

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

Có cách nào tốt hơn để tạo tham số yêu cầu SOAP với không gian tên và thuộc tính không?

Tôi đang tìm kiếm s.th. như sau (đây chỉ là một số mã giả sử dụng SoapVar API):

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

Tôi không thông thạo SOAP như tôi muốn, nhưng nó có hỗ trợ các yêu cầu với các thuộc tính không? (Tôi biết WSDL có các thuộc tính, nhưng nó xử lý các thuộc tính trong XML được gửi đến nó như thế nào?) Bạn có đang tạo dịch vụ hoặc đã được thiết lập chưa? Nếu đó là dịch vụ của bạn, tôi sẽ thả phần thuộc tính và di chuyển nó đến phần tử riêng của nó trong tham số. Có lẽ như là một phần tử không có giá trị, như '' – Anthony

+0

@Anthony: tôi không may điều khiển máy chủ SOAP và không ảnh hưởng đến định nghĩa dịch vụ, (khác, tất nhiên, tôi chỉ có thể làm cho thuộc tính là một phần tử –

Trả lời

0

SOAP không hỗ trợ thuộc tính, có thể là bạn nên sử dụng REST của thay!

EDIT: Vui lòng kiểm tra w3c phong cách cơ thể: "4.3 SOAP Body" và nhớ rằng bạn cần để mã hóa thông điệp của bạn với "xà phòng phong bì" không gian tên và mô tả loại XML của bạn thats tại sao, bạn có thể' t sử dụng các thuộc tính để mô tả dữ liệu tin nhắn của bạn.

Nhưng nếu bạn hỏi tôi, điều đó có thể được thực hiện! Bạn có thể sử dụng một trình phân tích cú pháp SoapClient tùy chỉnh hoặc một cái gì đó như thế và chuyển đổi tin nhắn của bạn như bạn muốn. Ví dụ về điều đó có thể là RSS trên SOAP http://www.ibm.com/developerworks/webservices/library/ws-soaprdf. Nhưng, vấn đề là bạn sẽ bỏ lỡ các thông tin mô tả về dữ liệu/loại tin nhắn của bạn và các khách hàng khác không thể dễ dàng hiểu được tin nhắn của bạn! Thực hành tốt nhất của tôi cho bạn là sử dụng các phần tử thay vì các thuộc tính, tôi biết bạn cần phải sửa lược đồ XML của bạn nhưng đó là cách nó đi hoặc chuyển sang một công nghệ khác.

+1

Tôi hiểu ý thích của bạn về REST trên SOAP nhưng câu trả lời này thực sự không giúp gì cả, nó không giúp nói với mọi người, không sử dụng công nghệ, khi họ cố gắng giải quyết vấn đề trong công nghệ cụ thể đó. bạn viết là simlpy sai: SOAP hỗ trợ các thuộc tính cf http: //www.w3.org/TR/2000/NOTE-SOAP-20000508/# _ Toc478383492 –

+0

Không, tôi thích SOAP hơn REST. Tôi đang phát triển với SOAP và PHP webservices trong một vài năm nay. Tôi đã sửa đổi câu trả lời của tôi một chút, tôi hy vọng điều này sẽ giúp. – RedAssBaboon

+0

Phản hồi của RAB về mặt kỹ thuật là chính xác. Vấn đề là một số người triển khai sẽ yêu cầu dữ liệu được truyền trong các thuộc tính. Mặt khác, việc thực hiện SoapVar của PHP tuân theo lá thư của luật và không hỗ trợ các thuộc tính như một thư viện XML bình thường. – method

-3

SOAP 1 hỗ trợ các thuộc tính. Dưới đây là một ví dụ về mã Perl sử dụng cả hai thuộc tính và giá trị (từ một khách hàng):

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

Câu hỏi quá tệ về PHP và không phải là Prel. –

3

Đối với điều này, bạn cần phải có nguồn gốc lớp từ SoapClient và Ghi đè __doRequest() phương pháp:

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

Tôi hy vọng điều này sẽ giải quyết vấn đề của bạn.

+0

Tôi không biết cách tùy chỉnh hàm __doRequest, nhưng tôi đã có một dòng mã này và nó đã hoạt động: // Thay thế không gian tên cho tất cả các loại đã biết $ request = str_replace ('RequestBase', 'ns1: RequestBase ', $ request); trả về cấp độ gốc :: __ doRequest ($ request, $ location, $ action, $ version); –

Các vấn đề liên quan