从 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.