我目前正在构建一个PHP脚本,它将采用Salesforce webhook POST,目前正在努力正确解析Soap XML字符串并使其进入可用状态。
我正在使用的XML字符串如下:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<notifications
xmlns="http://soap.sforce.com/2005/09/outbound">
<OrganizationId>00DN0000000XXXXXXX</OrganizationId>
<ActionId>04kN0000000XXXXXXX</ActionId>
<SessionId xsi:nil="true"/>
<EnterpriseUrl>https://cs6.salesforce.com/services/Soap/c/38.0/00DN0000000XXXXXXX</EnterpriseUrl>
<PartnerUrl>https://cs6.salesforce.com/services/Soap/u/38.0/00DN0000000XXXXXXX</PartnerUrl>
<Notification>
<Id>00DN0000000XXXXXXX</Id>
<sObject xsi:type="sf:Account"
xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
<sf:Id>00DN0000000XXXXXXX</sf:Id>
<sf:FirstName>Bill</sf:FirstName>
<sf:LastName>Jack</sf:LastName>
<sf:PersonEmail>abc@xyz.net</sf:PersonEmail>
<sf:PersonMobilePhone>0400000000</sf:PersonMobilePhone>
</sObject>
</Notification>
</notifications>
</soapenv:Body>
</soapenv:Envelope>
我用来提取数据的代码如下:
$xml = simplexml_load_string($xmlString);
$xml->registerXPathNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('ob', 'http://soap.sforce.com/2005/09/outbound');
$xml->registerXPathNamespace('sf', 'urn:sobject.enterprise.soap.sforce.com');
$notifications = $xml->xpath('//soapenv:Envelope/soapenv:Body/ob:notifications/ob:Notification/*');
我可以获得Notification
标记的子项,但无论我做什么,我都无法提取sObject
子项及其相关数据。
我试图摆弄名称空间,这是我怀疑我出错的地方,我试过的其他事情涉及使用通配符和其他XPath运算符无济于事。
我做错了什么意味着我无法通过xpath()
方法获取sObject?
答案 0 :(得分:0)
好的,所以我已经弄清楚发生了什么,并把它留在这里,希望任何遇到同一问题的人都会发现这个答案很有帮助。感谢IMSoP帮助我找到答案。
首先,SimpleXML的xpath()
方法返回一个数组,而不是XML对象,这从一开始就让生活变得困难。其次,如果您查看<notifications>
标记,您会看到它使用outbound
命名空间,在我的示例中,我将其别名为ob
。因此,Notification
和sObject
也被认为是同名命名空间的一部分,因为它们是命名空间元素的子元素,这意味着正确的xpath是
//soapenv:Envelope/soapenv:Body/ob:notifications/ob:Notification/ob:sObject
如上所述,在SimpleXML中,将返回一个数组,因此抓取第一个索引,并在children()
方法调用中使用提供的命名空间url for sObject,您将获得数据。
所以使用上面的例子XML
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<notifications
xmlns="http://soap.sforce.com/2005/09/outbound">
<OrganizationId>00DN0000000XXXXXXX</OrganizationId>
<ActionId>04kN0000000XXXXXXX</ActionId>
<SessionId xsi:nil="true"/>
<EnterpriseUrl>https://cs6.salesforce.com/services/Soap/c/38.0/00DN0000000XXXXXXX</EnterpriseUrl>
<PartnerUrl>https://cs6.salesforce.com/services/Soap/u/38.0/00DN0000000XXXXXXX</PartnerUrl>
<Notification>
<Id>00DN0000000XXXXXXX</Id>
<sObject xsi:type="sf:Account"
xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
<sf:Id>00DN0000000XXXXXXX</sf:Id>
<sf:FirstName>Bill</sf:FirstName>
<sf:LastName>Jack</sf:LastName>
<sf:PersonEmail>abc@xyz.net</sf:PersonEmail>
<sf:PersonMobilePhone>0400000000</sf:PersonMobilePhone>
</sObject>
</Notification>
</notifications>
</soapenv:Body>
</soapenv:Envelope>
我们可以通过以下方式获取数据:
$xml = simplexml_load_string($xmlString);
$xml->registerXPathNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('ob', 'http://soap.sforce.com/2005/09/outbound');
$sObject = $xml->xpath('//soapenv:Envelope/soapenv:Body/ob:notifications/ob:Notification/ob:sObject')[0];
$data = $sObject->children('urn:sobject.enterprise.soap.sforce.com');
var_dump($data);