SimpleXML解析嵌套名称空间-PHP
我在解析下面名为“q0:”的嵌套命名空间中的标记时遇到了一个小问题SimpleXML解析嵌套名称空间-PHP,php,namespaces,simplexml,Php,Namespaces,Simplexml,我在解析下面名为“q0:”的嵌套命名空间中的标记时遇到了一个小问题 //Tag that I am trying to parse <q0:CustomerTransactionId> 不是的子项,它是的子项,因此您需要在$reply中查找它,而不是$body:$reply2=$reply->children('q0',TRUE)->TransactionDetail 需要记住的重要一点是,->TagName操作符和->children()方法都只查看特定节点的直接子节点,而不
//Tag that I am trying to parse
<q0:CustomerTransactionId>
不是
的子项,它是
的子项,因此您需要在$reply
中查找它,而不是$body
:$reply2=$reply->children('q0',TRUE)->TransactionDetail代码>
需要记住的重要一点是,->TagName
操作符和->children()
方法都只查看特定节点的直接子节点,而不是像XPath那样进行“深度搜索”
实际上,看一下,v12:
和q0:
都是相同名称空间(“”)的别名,因此下一行可以是$reply2=$reply->TransactionDetail
。如果你只是说$reply=$body->children('http://fedex.com/ws/ship/v12“)->ProcessShipmentReply
与依赖别名相比,这变得更清晰(更安全,因为这些别名可能会更改)
顺便说一句,除非您将其用于其他用途,否则您还可以去掉所有XPath代码(包括所有registerXPathNamespace
调用),只需编写$body=$xml->children()http://schemas.xmlsoap.org/soap/envelope/“)->Body
(我很确定SOAP只允许每条消息有一个Body)。谢谢。我真的很感谢你的解释
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<soapenv:Body>
<v12:ProcessShipmentReply
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:v12="http://fedex.com/ws/ship/v12">
<v12:HighestSeverity>ERROR</v12:HighestSeverity>
<v12:Notifications>
<v12:Severity>ERROR</v12:Severity>
<v12:Source>ship</v12:Source>
<v12:Code>3058</v12:Code>
<v12:Message>Recipient Postal code or routing code is required</v12:Message>
<v12:LocalizedMessage>Recipient Postal code or routing code is required</v12:LocalizedMessage>
</v12:Notifications>
<q0:TransactionDetail xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q0="http://fedex.com/ws/ship/v12">
<q0:CustomerTransactionId>21445634</q0:CustomerTransactionId>
</q0:TransactionDetail><q0:Version xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q0="http://fedex.com/ws/ship/v12">
<q0:ServiceId>ship</q0:ServiceId>
<q0:Major>12</q0:Major>
<q0:Intermediate>0</q0:Intermediate>
<q0:Minor>0</q0:Minor>
</q0:Version>
</v12:ProcessShipmentReply>
</soapenv:Body>
</soapenv:Envelope>
$xml = simplexml_load_string($result, NULL, NULL, 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('env', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('v12', 'http://fedex.com/ws/ship/v12');
$xml->registerXPathNamespace('q0', 'http://fedex.com/ws/ship/v12');
$bodies = $xml->xpath('env:Body');
foreach($bodies as $body){
$reply = $body->children('v12', TRUE)->ProcessShipmentReply;
$reply2 = $body->children('q0', TRUE)->TransactionDetail;
$custInfoArr['status'] = (string) $reply->HighestSeverity;
if(strtolower($custInfoArr['status'])=="error"){
$custInfoArr['invoiceNum'] = (string)$reply2->CustomerTransactionId;
$custInfoArr['notificationSeverity']= (string) $reply->Notifications->Severity;
$custInfoArr['notificationSource']= (string) $reply->Notifications->Source;
$custInfoArr['notificationCode']= (string) $reply->Notifications->Code;
$custInfoArr['notificationMessage']= (string) $reply->Notifications->Message;
$custInfoArr['notificationLocalizedMessage']= (string) $reply->Notifications->LocalizedMessage;
}
$custInfoArr['trackingCode'] = (string) $reply->CompletedShipmentDetail->CompletedPackageDetails->TrackingIds->TrackingNumber;
$custInfoArr['labelCode'] = (string) $reply->CompletedShipmentDetail->CompletedPackageDetails->Label->Parts->Image;
$custInfoArr['labelCode'] = base64_decode($custInfoArr['labelCode']);
}