这是我使用的代码:
$doc = // SOAP Response
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
$xpath->registerNamespace('api', 'http://127.0.0.1/Integrics/Enswitch/API');
// Response:
if ($xpath->query('/soap:Envelope/soap:Body/api:get_cdrsResponse')->length < 1)
{
throw new EnswitchResponseFaultException();
}
它不断抛出这个异常我做错了什么?
这是我获得的回复(Pastebin link):
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><get_cdrsResponse
xmlns="http://www.flatplanetphone.net/Integrics/Enswitch/API">
<s-gensym3>
<scustomer xsi:type="xsd:string">4458</scustomer>
<recording xsi:type="xsd:string" />
<outgroup_name xsi:type="xsd:string">abc</outgroup_name>
<bill_type xsi:type="xsd:string">prepaid</bill_type>
</s-gensym3>
答案 0 :(得分:2)
您应该使用以下命令注册XML命名空间:
$xpath->registerNamespace('api', 'http://www.flatplanetphone.net/Integrics/Enswitch/API');
不
$xpath->registerNamespace('api', 'http://127.0.0.1/Integrics/Enswitch/API');
回复回复:
<get_cdrsResponse xmlns="http://www.flatplanetphone.net/Integrics/Enswitch/API">
无论此URL是否可解析都无关紧要,唯一重要的是字符串匹配。
答案 1 :(得分:2)
<强>简介强>
不知道你在哪里$xpath->registerNamespace('api', 'http://127.0.0.1/Integrics/Enswitch/API');
但不是有效namespace
去获取你可以使用的所有有效命名空间
$sxe = new SimpleXMLElement($xml);
print_r($sxe->getDocNamespaces(true));
输出
Array
(
[xsi] => http://www.w3.org/2001/XMLSchema-instance
[soapenc] => http://schemas.xmlsoap.org/soap/encoding/
[xsd] => http://www.w3.org/2001/XMLSchema
[soap] => http://schemas.xmlsoap.org/soap/envelope/
[] => http://www.flatplanetphone.net/Integrics/Enswitch/API
)
来自pastbin的XML
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><get_cdrsResponse
xmlns="http://www.flatplanetphone.net/Integrics/Enswitch/API">
<s-gensym3>
<scustomer xsi:type="xsd:string">4458</scustomer>
<recording xsi:type="xsd:string" />
<outgroup_name xsi:type="xsd:string">abc</outgroup_name>
<bill_type xsi:type="xsd:string">prepaid</bill_type>
</s-gensym3>
</get_cdrsResponse>
</soap:Body>
</soap:Envelope>';
解决方案
$sxe = new SimpleXMLElement($xml);
$sxe->registerXPathNamespace("api", "http://www.flatplanetphone.net/Integrics/Enswitch/API");
$path = $sxe->xpath("//api:s-gensym3");
$info = array_shift($path);
if (!$info)
throw new Exception("Invalid Response");
echo $info->scustomer, PHP_EOL;
echo $info->recording, PHP_EOL;
echo $info->outgroup_name, PHP_EOL;
echo $info->bill_type, PHP_EOL;
4458
abc
prepaid
======================================
======================================
处理多个孩子时,您可以忽略命名空间并使用SimpleXMLElement::children
示例
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<get_cdrsResponse xmlns="http://www.flatplanetphone.net/Integrics/Enswitch/API">
<s-gensym3>
<scustomer xsi:type="xsd:string">4458</scustomer>
<recording xsi:type="xsd:string" />
<outgroup_name xsi:type="xsd:string">abc</outgroup_name>
<bill_type xsi:type="xsd:string">prepaid14</bill_type>
</s-gensym3>
<s-gensym5>
<scustomer xsi:type="xsd:string">4458</scustomer>
<recording xsi:type="xsd:string" />
<outgroup_name xsi:type="xsd:string">abcd</outgroup_name>
<bill_type xsi:type="xsd:string">prepaid</bill_type>
</s-gensym5>
<s-gensym7>
<scustomer xsi:type="xsd:string">4458</scustomer>
<recording xsi:type="xsd:string" />
<outgroup_name xsi:type="xsd:string">abce</outgroup_name>
<bill_type xsi:type="xsd:string">prepaid13</bill_type>
</s-gensym7>
<s-gensym11>
<scustomer xsi:type="xsd:string">4458</scustomer>
<recording xsi:type="xsd:string" />
<outgroup_name xsi:type="xsd:string">abcf</outgroup_name>
<bill_type xsi:type="xsd:string">prepaid12</bill_type>
</s-gensym11>
</get_cdrsResponse>
</soap:Body>
</soap:Envelope>';
$sxe = new SimpleXMLElement($xml);
$response = $sxe->children('soap', true)->Body->children()->get_cdrsResponse;
foreach ( $response->children() as $gensym ) {
echo $gensym->scustomer, PHP_EOL;
echo $gensym->recording, PHP_EOL;
echo $gensym->outgroup_name, PHP_EOL;
echo $gensym->bill_type, PHP_EOL;
echo PHP_EOL;
echo PHP_EOL;
}
答案 2 :(得分:1)
当我更换你的行
if ($xpath->query('/soap:Envelope/soap:Body/api:get_cdrsResponse')->length < 1)
使用:
if ($xpath->query('/soap:Envelope/soap:Body/get_cdrsResponse')->length < 1)
并从get_cdrsResponse中删除'xmlns'部分。所以问题出在api:
部分。我注意到get_cdrsResponse中的xmlns返回404(http://www.flatplanetphone.net/Integrics/Enswitch/API),所以我建议开始修复它。