使用SOAP :: Lite在“method”元素中定义名称空间

问题描述:

我正在使用SOAP :: Lite连接到外部服务。经过与其他公司的多次反复试验和沟通,我发现了这个问题。使用SOAP :: Lite在“method”元素中定义名称空间

我的代码如下所示:

$soap = new SOAP::Lite 
    ->service($wsdl_link) 
    ->uri($url_link) 
    ->proxy($proxy_link) 
    ->on_action(sub { sprintf '"%s%s"', shift, shift }); 
my $resp = $soap->call('CreateAssignment',SOAP::Data->type('xml'=>$xml), 
           SOAP::Header->type('xml'=>$headXML)); 

这将产生以下XML:

<?xml version="1.0" encoding="UTF-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" > 
<soap:Header> 
... 
</soap:Header> 
<soap:Body> 
<CreateAssignment xmlns="url_link"> 
... 
</CreateAssignment></soap:Body></soap:Envelope> 

(其中url_link是有效的URL)

我需要定义额外的命名空间。我通过在我的代码中添加了->ns(namespace, prefix)来完成此操作。但是,这会将附加名称空间添加到“envelope”标记中。我被公司告知,名称空间需要位于“CreateAssignment”标签上。事实上,当我做出适当的改变并使用SOAP UI运行它时,它的运行非常好。

我曾尝试在我的xml中添加“CreateAssignment”标记,并且在没有方法的情况下运行call()函数。 SOAP :: Lite将xml封装在通用标记中。

我已经阅读了SOAP :: Lite文档,我询问了搜索引擎,我问过同事,没有人有答案。

有没有办法强制SOAP :: Lite把命名空间声明放在我需要它们的地方?

如果不是,什么是更好的模块使用?

+0

Re“*我被公司告知,名称空间需要位于”CreateAssignment“标签上。*”,您正在将名称空间分配给前缀,对吗? (这是没有任何意义的。)如果是这样,公司是错误的。 – ikegami

我最终坐下来和另一位同事坐在一起,阅读SOAP :: Lite的源代码 - 我们发现方法标签是在sub envelope中构建的。有一个if语句,由此模块将使用整个对象如果不是一个字符串对象一个SOAP ::数据对象被传递在作为该方法:

$soap = new SOAP::Lite 
->service($wsdl_link) 
->uri($url_link) 
->proxy($proxy_link) 
->on_action(sub { sprintf '"%s%s"', shift, shift }); 
my $resp = $soap->call('CreateAssignment',SOAP::Data->type('xml'=>$xml), 
           SOAP::Header->type('xml'=>$headXML)); 

elsif (UNIVERSAL::isa($method => 'SOAP::Data')) { 
      $body = $method; 
     } 

我从这个变

要这样:

$method = SOAP::Data->new(name=>'ns4:CreateAssignment'); 
$method->attr({'xmlns'=> $namespaceOne, 
      'xmlns:ns2'=> $namespaceTwo, 
      'xmlns:ns3'=> $namespaceThree, 
      'xmlns:ns4'=> $namespaceFour, 
      'xmlns:ns5'=> $namespaceFive}); 

$soap = new SOAP::Lite 
     ->service($wsdl_link) 
     ->uri($url_link) 
     ->proxy($proxy_link) 
     ->on_action(sub { sprintf '"%s%s"', shift, shift }); 

my $resp = $soap->call($method,SOAP::Data->type('xml'=>$xml), 
           SOAP::Header->type('xml'=>$headXML)); 

这造成我的方法标签完全按照要求公司:

<ns4:CreateAssignment xmlns="namespaceOne" xmlns:ns2="namespaceTwo" xmlns:ns3="namespaceThree" xmlns:ns4="namespaceFour" xmlns:ns5="namespaceFive"> 
... 
</ns4:CreateAssignment>