2009-08-25 75 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