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

时间:2017-02-03 20:13:08

标签: perl soap soaplite

我正在使用SOAP :: Lite连接到外部服务。经过多次试验和错误以及与其他公司的沟通,我发现了这个问题。

我的代码如下所示:

$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是有效的网址)

我需要定义其他名称空间。我通过在代码中添加->ns(namespace, prefix)来完成此操作。但是,这会将其他名称空间添加到“envelope”标记中。我被公司告知,名称空间需要位于“CreateAssignment”标签上。实际上,当我进行适当的更改并使用SOAP UI运行它时,它可以很好地工作。

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

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

有没有办法强制SOAP :: Lite将命名空间声明放在我需要的位置?

如果没有,什么是更好的模块?

1 个答案:

答案 0 :(得分:0)

我最后和另一位同事坐下来阅读SOAP :: Lite的源代码 - 我们发现方法标签是在sub envelope中构建的。有一个if语句,模块将使用整个对象,而不是字符串对象,SOAP :: Data对象作为方法传入:

elsif (UNIVERSAL::isa($method => 'SOAP::Data')) {
            $body = $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));

对此:

$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>