如何为 Perl 使用 SOAP API?
How to use a SOAP API for Perl?
我正在尝试调整以下 PHP code in Perl. It's a bioDBnet SOAP API. I tried following the example on the SOAP::WSDL 模块(在 SYNOPSIS 下),但它无法连接。我收到一条错误消息:
尝试 1
#!perl -w
use SOAP::WSDL;
my $client = SOAP::WSDL->new(
wsdl => "http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet.wsdl",
);
错误信息:cannot import document for namespace >http://schemas.xmlsoap.org/soap/encoding/< without location at /Library/Perl/5.16/SOAP/WSDL/Expat/WSDLParser.pm line 90.
尝试 2
接下来我尝试使用 SOAP::LITE 模块。我遵循了 HERE 中的示例代码(在 6.b.client 下)。
#!perl -w
use SOAP::Lite;
my $client = SOAP::Lite ->
service('http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet.wsdl');
my %db2dbParams;
$db2dbParams{'input'} = "Gene Symbol";
$db2dbParams{'outputs'} = "Gene ID, Ensembl Gene ID";
$db2dbParams{'inputValues'} = "MYC,A1BG";
$db2dbParams{'taxonId'} = "9606";
$db2dbRes = $client->db2db(%db2dbParams);
print $db2dbRes;
上面的代码没有打印任何东西。我如何让 bioDBnet SOAP API 为 Perl 工作?
除 db2db 部分外,您的第二个脚本有效。
我的猜测是发送到服务器的 SOAP XML 信封在使用 SOAP::LITE.
发送时状态不佳
我在第二行启用了调试:
#!/usr/bin/perl -w
use SOAP::Lite +trace =>'debug';
#use SOAP::Lite;
my $client = SOAP::Lite->service('http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet.wsdl');
$inputs = $client->getInputs();
print $inputs;
$input = "Gene Symbol";
$outputs = $client->getOutputsForInput($input);
print $outputs;
$dirOutputs = $client->getDirectOutputsForInput($input);
print $dirOutputs;
.. 从你的尝试 2:
# doesn't work, the created XML envelope is not in a good shape
my %db2dbParams;
$db2dbParams{'input'} = "Gene Symbol";
$db2dbParams{'outputs'} = "Gene ID, Ensembl Gene ID";
$db2dbParams{'inputValues'} = "MYC,A1BG";
$db2dbParams{'taxonId'} = "9606";
$db2dbRes = $client->db2db(%db2dbParams);
print $db2dbRes;
..我也尝试使用SOAP:Data重写它...但失败了。
# doesn't work, the created XML envelope is not in a good shape
$db2dbRes = $client->db2db(
SOAP::Data->name("db2dbParams")->type("ns1:db2dbParams")->prefix("ns1:db2db")->uri("urn:bioDBnet") =>
SOAP::Data->type("string")->name("input" => "Gene Symbol"),
SOAP::Data->type("string")->name("inputValues" => "MYC,MTOR"),
SOAP::Data->type("string")->name("outputs" => "Gene ID, Affy ID"),
SOAP::Data->type("string")->name("taxonId" => "9606")
);
print $db2dbRes;
切换到 PHP 以查看工作请求。
我已在 PHP 脚本上启用调试以打印请求 headers
并从 PHP 获取正在工作的 XML 请求,并将其作为来自 PERL 的 POST 内容重新使用。基本上,通过在 SoapClient 上添加跟踪参数,然后转储最后一个请求 headers.
<?php
$wsdl = "http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet.wsdl";
$client = new SoapClient($wsdl, ['trace' => 1]);
$inputs = $client->getInputs();
print $inputs;
$input = "Gene Symbol";
$outputs = $client->getOutputsForInput($input);
print $outputs;
$dirOutputs = $client->getDirectOutputsForInput($input);
print $dirOutputs;
$db2dbParams['input'] = "Gene Symbol";
$db2dbParams['outputs'] = "Gene ID, Ensembl Gene ID";
$db2dbParams['inputValues'] = "MYC,A1BG";
$db2dbParams['taxonId'] = "9606";
$db2dbRes = $client->db2db($db2dbParams);
print $db2dbRes;
echo "====== REQUEST HEADERS =====" . PHP_EOL;
var_dump($client->__getLastRequestHeaders());
echo "========= REQUEST ==========" . PHP_EOL;
var_dump($client->__getLastRequest());
echo "========= RESPONSE =========" . PHP_EOL;
var_dump($db2dbRes);
这将打印 headers 和 XML,预期输出为:
Gene Symbol Gene ID Ensembl Gene ID
MYC 4609 ENSG00000136997
A1BG 1 ENSG00000121410
我将 "working" XML 请求数据包含在 $message 中并执行 POST 请求。
#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
use HTTP::Request;
my $message = '<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:bioDBnet" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:db2db>
<db2dbParams xsi:type="ns1:db2dbParams">
<input xsi:type="xsd:string">Gene Symbol</input>
<taxonId xsi:type="xsd:string">9606</taxonId>
<inputValues xsi:type="xsd:string">MYC,A1BG</inputValues>
<outputs xsi:type="xsd:string">Gene ID, Ensembl Gene ID</outputs>
</db2dbParams>
</ns1:db2db>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
my $userAgent = LWP::UserAgent->new();
my $request = HTTP::Request->new(POST => 'http://biodbnet.abcc.ncifcrf.gov/webServices/biodbnetSoapServer.php'); # ?debug=1
$request->content($message);
$request->content_type("text/xml; charset=utf-8");
my $response = $userAgent->request($request);
if($response->code == 200) {
print $response->as_string;
}
else {
print $response->error_as_HTML;
}
最后:在 header 输出旁边我们终于得到了一些数据:
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:db2dbResponse>
<return xsi:type="xsd:string">Gene Symbol Gene ID Ensembl Gene ID
MYC 4609 ENSG00000136997 A1BG 1 ENSG00000121410
</return>
</ns1:db2dbResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
现在,您需要做的就是从 $response->as_string
中提取 ns1:db2dbResponse
中的 return
元素(可能使用 LibXML)。
换句话说:这会绕过 SOAP::Lite 并使用 LWP 和一个带有 XML 的简单 POST 请求,解析 XML 响应。您丢失了自动提取,必须手动处理 return 数据。
不要使用 SOAP::Lite 服务方法,大多数情况下它不起作用。
手动构建 soap 结构。我尝试尽可能地遵循 php xml,尽管大多数前缀都不是必需的。
use strict;
use warnings;
use Data::Dumper;
use SOAP::Lite;
#use SOAP::Lite +trace=>'all';
$uri = 'urn:bioDBnet';
$proxy = 'http://biodbnet.abcc.ncifcrf.gov/webServices/biodbnetSoapServer.php';
$tns = 'urn:bioDBnet';
$soap = SOAP::Lite->new(uri => $uri,proxy => $proxy);
$soap->envprefix('SOAP-ENV');
$soap->encprefix('SOAP-ENC');
$soap->ns($tns,'tns1');
$soap->on_action(sub{$tns.'#db2db'});
@request = (SOAP::Data->name(db2dbParams => \SOAP::Data->value(
SOAP::Data->name(input => 'Gene Symbol'),
SOAP::Data->name(outputs => 'Gene ID, Ensembl Gene ID'),
SOAP::Data->name(inputValues => 'MYC,A1BG'),
SOAP::Data->name(taxonId => 9606),
))->type('ns1:db2dbParams'),
);
$db2db = $soap->db2db(@request);
if ($match = $db2db->match('/Envelope/Body/db2dbResponse')) {
print "match ok: $match\n";
$result = $db2db->result;
print Dumper($result);
} else {
print "match nok: $match\n";
}
这会从服务器生成所需的输出。
我正在尝试调整以下 PHP code in Perl. It's a bioDBnet SOAP API. I tried following the example on the SOAP::WSDL 模块(在 SYNOPSIS 下),但它无法连接。我收到一条错误消息:
尝试 1
#!perl -w
use SOAP::WSDL;
my $client = SOAP::WSDL->new(
wsdl => "http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet.wsdl",
);
错误信息:cannot import document for namespace >http://schemas.xmlsoap.org/soap/encoding/< without location at /Library/Perl/5.16/SOAP/WSDL/Expat/WSDLParser.pm line 90.
尝试 2
接下来我尝试使用 SOAP::LITE 模块。我遵循了 HERE 中的示例代码(在 6.b.client 下)。
#!perl -w
use SOAP::Lite;
my $client = SOAP::Lite ->
service('http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet.wsdl');
my %db2dbParams;
$db2dbParams{'input'} = "Gene Symbol";
$db2dbParams{'outputs'} = "Gene ID, Ensembl Gene ID";
$db2dbParams{'inputValues'} = "MYC,A1BG";
$db2dbParams{'taxonId'} = "9606";
$db2dbRes = $client->db2db(%db2dbParams);
print $db2dbRes;
上面的代码没有打印任何东西。我如何让 bioDBnet SOAP API 为 Perl 工作?
除 db2db 部分外,您的第二个脚本有效。 我的猜测是发送到服务器的 SOAP XML 信封在使用 SOAP::LITE.
发送时状态不佳我在第二行启用了调试:
#!/usr/bin/perl -w
use SOAP::Lite +trace =>'debug';
#use SOAP::Lite;
my $client = SOAP::Lite->service('http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet.wsdl');
$inputs = $client->getInputs();
print $inputs;
$input = "Gene Symbol";
$outputs = $client->getOutputsForInput($input);
print $outputs;
$dirOutputs = $client->getDirectOutputsForInput($input);
print $dirOutputs;
.. 从你的尝试 2:
# doesn't work, the created XML envelope is not in a good shape
my %db2dbParams;
$db2dbParams{'input'} = "Gene Symbol";
$db2dbParams{'outputs'} = "Gene ID, Ensembl Gene ID";
$db2dbParams{'inputValues'} = "MYC,A1BG";
$db2dbParams{'taxonId'} = "9606";
$db2dbRes = $client->db2db(%db2dbParams);
print $db2dbRes;
..我也尝试使用SOAP:Data重写它...但失败了。
# doesn't work, the created XML envelope is not in a good shape
$db2dbRes = $client->db2db(
SOAP::Data->name("db2dbParams")->type("ns1:db2dbParams")->prefix("ns1:db2db")->uri("urn:bioDBnet") =>
SOAP::Data->type("string")->name("input" => "Gene Symbol"),
SOAP::Data->type("string")->name("inputValues" => "MYC,MTOR"),
SOAP::Data->type("string")->name("outputs" => "Gene ID, Affy ID"),
SOAP::Data->type("string")->name("taxonId" => "9606")
);
print $db2dbRes;
切换到 PHP 以查看工作请求。 我已在 PHP 脚本上启用调试以打印请求 headers 并从 PHP 获取正在工作的 XML 请求,并将其作为来自 PERL 的 POST 内容重新使用。基本上,通过在 SoapClient 上添加跟踪参数,然后转储最后一个请求 headers.
<?php
$wsdl = "http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet.wsdl";
$client = new SoapClient($wsdl, ['trace' => 1]);
$inputs = $client->getInputs();
print $inputs;
$input = "Gene Symbol";
$outputs = $client->getOutputsForInput($input);
print $outputs;
$dirOutputs = $client->getDirectOutputsForInput($input);
print $dirOutputs;
$db2dbParams['input'] = "Gene Symbol";
$db2dbParams['outputs'] = "Gene ID, Ensembl Gene ID";
$db2dbParams['inputValues'] = "MYC,A1BG";
$db2dbParams['taxonId'] = "9606";
$db2dbRes = $client->db2db($db2dbParams);
print $db2dbRes;
echo "====== REQUEST HEADERS =====" . PHP_EOL;
var_dump($client->__getLastRequestHeaders());
echo "========= REQUEST ==========" . PHP_EOL;
var_dump($client->__getLastRequest());
echo "========= RESPONSE =========" . PHP_EOL;
var_dump($db2dbRes);
这将打印 headers 和 XML,预期输出为:
Gene Symbol Gene ID Ensembl Gene ID
MYC 4609 ENSG00000136997
A1BG 1 ENSG00000121410
我将 "working" XML 请求数据包含在 $message 中并执行 POST 请求。
#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
use HTTP::Request;
my $message = '<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:bioDBnet" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:db2db>
<db2dbParams xsi:type="ns1:db2dbParams">
<input xsi:type="xsd:string">Gene Symbol</input>
<taxonId xsi:type="xsd:string">9606</taxonId>
<inputValues xsi:type="xsd:string">MYC,A1BG</inputValues>
<outputs xsi:type="xsd:string">Gene ID, Ensembl Gene ID</outputs>
</db2dbParams>
</ns1:db2db>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
my $userAgent = LWP::UserAgent->new();
my $request = HTTP::Request->new(POST => 'http://biodbnet.abcc.ncifcrf.gov/webServices/biodbnetSoapServer.php'); # ?debug=1
$request->content($message);
$request->content_type("text/xml; charset=utf-8");
my $response = $userAgent->request($request);
if($response->code == 200) {
print $response->as_string;
}
else {
print $response->error_as_HTML;
}
最后:在 header 输出旁边我们终于得到了一些数据:
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://biodbnet.abcc.ncifcrf.gov/webServices/bioDBnet"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:db2dbResponse>
<return xsi:type="xsd:string">Gene Symbol Gene ID Ensembl Gene ID
MYC 4609 ENSG00000136997 A1BG 1 ENSG00000121410
</return>
</ns1:db2dbResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
现在,您需要做的就是从 $response->as_string
中提取 ns1:db2dbResponse
中的 return
元素(可能使用 LibXML)。
换句话说:这会绕过 SOAP::Lite 并使用 LWP 和一个带有 XML 的简单 POST 请求,解析 XML 响应。您丢失了自动提取,必须手动处理 return 数据。
不要使用 SOAP::Lite 服务方法,大多数情况下它不起作用。 手动构建 soap 结构。我尝试尽可能地遵循 php xml,尽管大多数前缀都不是必需的。
use strict;
use warnings;
use Data::Dumper;
use SOAP::Lite;
#use SOAP::Lite +trace=>'all';
$uri = 'urn:bioDBnet';
$proxy = 'http://biodbnet.abcc.ncifcrf.gov/webServices/biodbnetSoapServer.php';
$tns = 'urn:bioDBnet';
$soap = SOAP::Lite->new(uri => $uri,proxy => $proxy);
$soap->envprefix('SOAP-ENV');
$soap->encprefix('SOAP-ENC');
$soap->ns($tns,'tns1');
$soap->on_action(sub{$tns.'#db2db'});
@request = (SOAP::Data->name(db2dbParams => \SOAP::Data->value(
SOAP::Data->name(input => 'Gene Symbol'),
SOAP::Data->name(outputs => 'Gene ID, Ensembl Gene ID'),
SOAP::Data->name(inputValues => 'MYC,A1BG'),
SOAP::Data->name(taxonId => 9606),
))->type('ns1:db2dbParams'),
);
$db2db = $soap->db2db(@request);
if ($match = $db2db->match('/Envelope/Body/db2dbResponse')) {
print "match ok: $match\n";
$result = $db2db->result;
print Dumper($result);
} else {
print "match nok: $match\n";
}
这会从服务器生成所需的输出。