php - 从 Soap Response PHP 获取属性值
问题描述
我得到了预期的肥皂响应,然后转换为数组。这是我的代码:
$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
解决方案
您在如何解析 XML 方面遵循了一些非常糟糕的建议,并且完全抛弃了 SimpleXML 的功能。
具体来说,您无法运行该attributes()
方法的原因是您已经使用这个丑陋的 hack 将 SimpleXML 对象转换为普通数组:
$array = json_decode( str_replace('@', '', json_encode((array)$body)), TRUE);
要按照作者的意图使用 SimpleXML,我建议您阅读:
由于您没有在问题中粘贴实际的 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_replace
or做任何奇怪的事情json_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 以进行更复杂的操作。
推荐阅读
- android - MIFARE 卡在 Android 设备上复制
- javascript - 订阅 paramMap 会破坏路由示例?
- react-native - 使用 SectionList 时无法读取未定义的属性“长度”
- amazon-ec2 - Terraform - 从 aws 实例资源输出实例 ID - 一次一个
- javascript - 在php中将本地数据库与远程数据库同步
- r - R闪亮:如何将滑块和单选按钮链接到ggplot
- c# - 使用二叉搜索树搜索超过 100 万条已加载的 SQL 行
- scala - 闭包内的对象生命周期
- c - C:[错误]链表快速排序
- c# - C# - 在某些值之间替换文本文件中的字符串