使用 SOAP::Lite 在 "method" 元素中定义命名空间

Define namespaces in the "method" element using SOAP::Lite

我正在使用 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 是有效的 url)

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

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

我看了SOAP::Lite文档,我问过搜索引擎,我问过同事,没有人有答案。

有没有办法强制 SOAP::Lite 将名称空间声明放在我需要的地方?

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

我最后和另一位同事坐下来阅读 SOAP::Lite 的源代码——我们发现方法标签是在 sub envelope 中构建的。有一个 if-statement 如果传入 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>