1

我正在使用 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 将命名空间声明放在我需要的地方?

如果没有,使用什么模块更好?

4

1 回答 1

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>
于 2017-02-07T18:15:40.817 回答