xml - 使用 SOAP::Lite 形成 SOAP 请求 xml
问题描述
我在使用 SOAP::Lite perl-module 形成 SOAP 请求时遇到了一些麻烦。
这是 WSDL 模式:
<wsdl:definitions xmlns:p1="http://example.com/SOAP/PList" name="SI_PList_2_SRM_SO" targetNamespace="http://example.com/SOAP/PList">
<wsdl:documentation />
<wsp:UsingPolicy wsdl:required="true" />
<wsp:Policy wsu:Id="OP_SI_PList_2_SRM_SO" />
<wsdl:types>
<xsd:schema xmlns="http://example.com/SOAP/PList" targetNamespace="http://example.com/SOAP/PList">
<xsd:element name="MT_PList_Response" type="DT_PList_Response" />
<xsd:element name="MT_PList_Request" type="DT_PList_Request" />
<xsd:simpleType name="DT_PList_Request">
</xsd:simpleType>
<xsd:complexType name="DT_PList_Response">
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="MT_PList_Request">
<wsdl:documentation />
<wsdl:part name="MT_PList_Request" element="p1:MT_PList_Request" />
</wsdl:message>
<wsdl:message name="MT_PList_Response">
<wsdl:documentation />
<wsdl:part name="MT_PList_Response" element="p1:MT_PList_Response" />
</wsdl:message>
<wsdl:portType name="SI_PList_2_SRM_SO">
<wsdl:operation name="SI_PList_2_SRM_SO">
<wsdl:documentation />
<wsp:Policy>
<wsp:PolicyReference URI="#OP_SI_PList_2_SRM_SO" />
</wsp:Policy>
<wsdl:input message="p1:MT_PList_Request" />
<wsdl:output message="p1:MT_PList_Response" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SI_PList_2_SRM_SOBinding" type="p1:SI_PList_2_SRM_SO">
<wsdl:operation name="SI_PList_2_SRM_SO"/>
</wsdl:binding>
<wsdl:service name="SI_PList_2_SRM_SOService">
<wsdl:port name="HTTPS_Port" binding="p1:SI_PList_2_SRM_SOBinding">
<soap:address xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" location="https://s.example.com/api/etender/SI_PList_2_SRM_SO" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
使用 SOAP API 的说明告诉我应该调用过程 SI_PList_2_SRM_SO。我写了简单的测试脚本:
use SOAP::Lite +trace => [ transport => sub { say $_[0]->as_string } ];
my $api_host = "http://s.example.com/srm/api/etender/wsdl";
my $api_namespace = "http://example.com/SOAP/PList";
#my $soap = SOAP::Lite->new(uri => $api_namespace, proxy => $api_host);
my $soap = SOAP::Lite->service($api_host);
$soap->serializer->envprefix('soapenv');
my $result = $soap->SI_PList_2_SRM_SO();
它形成请求:
<soapenv:Envelope xmlns:p1="http://example.com/SOAP/PList" >
<soapenv:Body>
<p1:SI_PList_2_SRM_SO xsi:nil="true" />
</soapenv:Body>
</soapenv:Envelope>
但是从对服务的 SOAP 服务器端的支持我知道正确的请求 xml 必须是:
<soapenv:Envelope xmlns:get="http://example.com/SOAP/PList">
<soapenv:Header/>
<soapenv:Body>
<get:MT_PList_Request>test</get:MT_PList_Request>
</soapenv:Body>
</soapenv:Envelope>
所以我应该在 Body 中有另一个标签。我还检查了SOAP Client Test Service,它用 MT_PList_Request 标签形成了正确的请求 XML。
如果我直接使用 MT_PList_Request,我预计会收到错误“无法识别的方法 'MT_PList_Request'。可用方法列表:SI_PList_2_SRM_SO”
我也不能使用像这样发送原始 XML 的方法
my $element = SOAP::Data->type('xml' => $xml);
my $result = $soap->SI_PList_2_SRM_SO($element);
因为使用参数调用的 SI_PList_2_SRM_SO 得到异常“未指定类型 'DT_PList_Request' 的架构/命名空间”。
如果我将service
方法更改为new
方法,预计什么都不会改变,无论如何请求 xml 有错误的标签。
解决方案
推荐阅读
- angular - 如何在 2020 年的 Visual Studio 代码中调试在 Android 模拟器上运行的 Ionic 应用程序?
- woocommerce - 我们可以使用 csv 文件从 woocommerce 导入产品到 shopify 吗?
- google-assistant-sdk - Iter 获得徽章“使用 Google 助理”
- vue.js - 如果字段包含数字,如何禁用按钮?Vue JS
- javascript - Material UI 中的自定义媒体查询
- python - 循环遍历 csv 文件中的单词并在 python 中替换
- css - 在 CSS / SCSS 中具有类的下一个兄弟姐妹
- javascript - 传单标记集群自动
- vim - 在vim中的一个命令中替换模式之前和之后的文本
- ffmpeg - ffmpeg 到 kurento rtp 流断断续续的视频问题