从Soap Response PHP获取属性值



我得到了预期的soap响应,然后转换为数组。这是我的代码:

$response = $client->__getLastResponse();
$response = preg_replace("/(</?)(w+):([^>]*>)/", "$1$2$3", $response);
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//soapBody')[0];
$array = json_decode( str_replace('@', '', json_encode((array)$body)), TRUE); 
print_r($array);

这是输出:

Array ( 
[GetCompanyCodeResponse] => Array ( 
[GetCompanyCodeResult] => Array ( 
[Customers] => Array ( 
[Customer] => Array ( 
[attributes] => Array ( 
[CustomerNo] => 103987 
[CustomerName] => epds api testers Inc 
[ContactId] => 219196 
) 
) 
) 
) 
) 

如何回显ContactId?我试过以下几种:

$att = $array->attributes();
$array->attributes()->{'ContactId'};
print_r($array);

我得到以下错误:

Fatal error: Uncaught Error: Call to a member function attributes() on array 

也尝试过:

$array->Customer['CustomerId'];

我得到以下错误:

Notice: Trying to get property 'Customer' of non-object

期望得到219196

我找到了上述问题的解决方案。不确定这是否是最优雅的方法,但它会按预期返回结果。如果有更有效的方法来获取ContactId,我愿意接受建议。

print_r($array['GetCompanyCodeResponse']['GetCompanyCodeResult']
['Customers']['Customer']['attributes']['ContactId']);

关于如何解析XML,您遵循了一些非常糟糕的建议,并完全放弃了SimpleXML的功能。

具体来说,您不能运行attributes()方法的原因是您已经使用以下丑陋的破解将SimpleXML对象转换为普通数组:

$array = json_decode( str_replace('@', '', json_encode((array)$body)), TRUE); 

要按照作者的意图使用SimpleXML,我建议您阅读:

  • PHP手册中的示例
  • 这个关于处理XML命名空间的参考答案

由于您没有在问题中粘贴实际的XML,我猜它看起来是这样的:

<?xml version = "1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
<soap:Body xmlns="http://www.example.org/companyInfo">
<GetCompanyCodeResponse>
<GetCompanyCodeResult>
<Customers>
<Customer CustomerNo="103987" CustomerName="epds api testers Inc" ContactId="219196" />
</Customers>
</GetCompanyCodeResult>
</GetCompanyCodeResponse>
</soap:Body>
</soap:Envelope>

如果是在$response中,我们不需要对str_replacejson_encode做任何奇怪的事情,我们可以使用SimpleXML中内置的方法来导航XML:

$xml = new SimpleXMLElement($response);
// The Body is in the SOAP Envelope namespace
$body = $xml->children('http://www.w3.org/2001/12/soap-envelope')->Body;
// The element inside that is in some other namespace
$innerResponse = $body->children('http://www.example.org/companyInfo')->GetCompanyCodeResponse;
// We need to traverse the XML to get to the node we're interested in
$customer = $innerResponse->GetCompanyCodeResult->Customers->Customer;
// Unprefixed attributes aren't technically in any namespace (an oddity in the XML namespace spec!)
$attributes = $customer->attributes(null);
// Here's the value you were looking for
echo $attributes['ContactId'];

与您以前的代码不同,这不会在以下情况下中断:

  • 服务器开始使用不同的本地前缀而不是soap:,或者在GetCompanyCodeResponse元素上添加前缀
  • 响应返回多个Customer(->Customer始终表示与->Customer[0]相同,即具有该名称的第一个子元素(
  • Customer元素具有子元素或文本内容以及属性

它还允许您使用SimpleXML的其他功能,如使用xpath表达式搜索文档,甚至切换到完整的DOM API以进行更复杂的操作。

最新更新