使用 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>
我正在使用 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>