从 XML 文件中为 SoapClient 请求获取正确的数据
Getting the correct data from an XML file for a SoapClient request
为了获得参考点,让我们使用这个 public WSDL:https://www.dataaccess.com/webservicesserver/NumberConversion.wso?WSDL
现在这个东西应该接受以下xml:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<NumberToWords xmlns="http://www.dataaccess.com/webservicesserver/">
<ubiNum>500</ubiNum>
</NumberToWords>
</soap:Body>
</soap:Envelope>
这是代码:
$requestData = simplexml_load_file($file);
//enabling or disabling the following line does not seem to make a difference, but I used it at some point to see that it does load something in there
$requestData->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");
//print_r($requestData->xpath('//soap:Body')); //I was using this to check that the data is actually there, and it is...
$webService = new SoapClient($url);
$result = $webService->NumberToWords($requestData);
print_r($result)
我收到了这样漂亮的回复:
stdClass Object
(
[NumberToWordsResult] => zero
)
我认为这与 simpleXML 加载数据的方式有关,但我没有弄清楚我应该做什么。
附带说明一下,如果我尝试手动设置数据:
$requestData = ["ubiNum"=>500];
它有效,但我真的很想弄清楚 xml parsing/sending
是怎么回事
另外如果有兴趣,我注释掉print_r
的结果如下
Array
(
[0] => SimpleXMLElement Object
(
[NumberToWords] => SimpleXMLElement Object
(
[ubiNum] => 500
)
)
)
如果您使用的是 SoapClient,则不需要自己构建整个 XML。根据服务的不同,您需要传递样式单个变量,或者“body”的内容。
正如你所说,你可以 运行:
$webService = new SoapClient($url);
$result = $webService->NumberToWords(["ubiNum"=>500]);
在下方,SoapClient class 正在为您生成 XML 的其余部分并将其作为 HTTP 请求发送。
如果您想从 XML 文档中获取数据,您需要只提取该部分,而不是尝试在参数内发送整个 SOAP 信封。在此示例中,您需要导航到“NumberToWords”元素;参见 this reference question for tips on navigating the XML namespaces 但在此示例中,您将使用如下内容:
$requestData = simplexml_load_file($file);
$soapBody = $requestData->children('http://schemas.xmlsoap.org/soap/envelope/')->Body;
$numberToWords = $soapBody->children('http://www.dataaccess.com/webservicesserver/')->NumberToWords;
// Or to get the 500 directly:
$ubiNum = (int)$numberToWords->ubiNum;
或者,您可以忽略 SoapClient class,自己构建 XML,然后 post 使用像 Guzzle 这样的 HTTP 客户端。通常您唯一需要的额外步骤是设置正确的“SOAPAction”HTTP header.
为了获得参考点,让我们使用这个 public WSDL:https://www.dataaccess.com/webservicesserver/NumberConversion.wso?WSDL
现在这个东西应该接受以下xml:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<NumberToWords xmlns="http://www.dataaccess.com/webservicesserver/">
<ubiNum>500</ubiNum>
</NumberToWords>
</soap:Body>
</soap:Envelope>
这是代码:
$requestData = simplexml_load_file($file);
//enabling or disabling the following line does not seem to make a difference, but I used it at some point to see that it does load something in there
$requestData->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");
//print_r($requestData->xpath('//soap:Body')); //I was using this to check that the data is actually there, and it is...
$webService = new SoapClient($url);
$result = $webService->NumberToWords($requestData);
print_r($result)
我收到了这样漂亮的回复:
stdClass Object
(
[NumberToWordsResult] => zero
)
我认为这与 simpleXML 加载数据的方式有关,但我没有弄清楚我应该做什么。
附带说明一下,如果我尝试手动设置数据:
$requestData = ["ubiNum"=>500];
它有效,但我真的很想弄清楚 xml parsing/sending
是怎么回事另外如果有兴趣,我注释掉print_r
的结果如下
Array
(
[0] => SimpleXMLElement Object
(
[NumberToWords] => SimpleXMLElement Object
(
[ubiNum] => 500
)
)
)
如果您使用的是 SoapClient,则不需要自己构建整个 XML。根据服务的不同,您需要传递样式单个变量,或者“body”的内容。
正如你所说,你可以 运行:
$webService = new SoapClient($url);
$result = $webService->NumberToWords(["ubiNum"=>500]);
在下方,SoapClient class 正在为您生成 XML 的其余部分并将其作为 HTTP 请求发送。
如果您想从 XML 文档中获取数据,您需要只提取该部分,而不是尝试在参数内发送整个 SOAP 信封。在此示例中,您需要导航到“NumberToWords”元素;参见 this reference question for tips on navigating the XML namespaces 但在此示例中,您将使用如下内容:
$requestData = simplexml_load_file($file);
$soapBody = $requestData->children('http://schemas.xmlsoap.org/soap/envelope/')->Body;
$numberToWords = $soapBody->children('http://www.dataaccess.com/webservicesserver/')->NumberToWords;
// Or to get the 500 directly:
$ubiNum = (int)$numberToWords->ubiNum;
或者,您可以忽略 SoapClient class,自己构建 XML,然后 post 使用像 Guzzle 这样的 HTTP 客户端。通常您唯一需要的额外步骤是设置正确的“SOAPAction”HTTP header.