2009-08-25 70 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請求參數?

我在找s.th.像下面的(這使用SoapVar API只是一些僞代碼):

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

我不像SOAP那樣精通SOAP,但它是否支持具有屬性的請求? (我知道WSDL具有屬性,但是它如何處理髮送給它的XML中的屬性?)您是在創建服務還是已經設置好了?如果它是你的服務,我會刪除屬性部分,並將其移動到參數中它自己的元素。也許作爲一個無價值的元素,比如'' – Anthony 2009-08-25 10:39:58

+0

@Anthony:我不幸地不控制SOAP服務器,並且對服務定義沒有影響;(當然,我可以將屬性設置爲一個元素 – 2009-08-25 18:30:48

回答

0

SOAP不支持的屬性,可能是你應該使用REST!

編輯: 請檢查機關作風W3C:「4.3的SOAP Body」,記住 你需要用「肥皂信封」命名編碼的消息,這就是形容 你的XML類型的原因,你可以」 t使用屬性來描述你的消息數據。

但是,如果你問我,它可以成爲可能!您可以使用自定義的SoapClient解析器或類似的東西,並根據需要轉換您的消息。 一個例子可能是RSS over SOAP http://www.ibm.com/developerworks/webservices/library/ws-soaprdf。 但是,問題在於您會錯過有關您的消息數據/類型的描述性信息,而其他客戶無法輕鬆理解您的消息!

我的最佳做法是使用元素而不是屬性, 我知道您需要修復您的XML模式,但這就是它走向或切換到其他技術的方式。

+1

我明白你對REST over SOAP的喜歡,但這個答案根本沒有幫助,當他們試圖解決特定技術中的問題時,不會告訴人們,不要使用技術。你寫的是simlpy錯誤的:SOAP確實支持屬性。cf http://www.w3。org/TR/2000/NOTE-SOAP-20000508 /#_ Toc478383492 – 2009-08-28 14:53:07

+0

沒有我比REST更喜歡SOAP。我現在用SOAP和PHP webservices開發了幾年。我已經修改了我的答案,我希望這有助於。 – RedAssBaboon 2009-08-28 18:50:38

+0

RAB的回覆在技術上是正確的。問題是有些實現者需要傳遞屬性。另一方面,PHP的SoapVar實現遵循法律規定,並且不會像普通的XML庫那樣提供屬性幫助。 – method 2010-09-27 03:02:12

-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。 – 2011-08-22 09:08:55

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); – 2015-07-01 07:20:43