在 PHP SimpleXML 对象、SOAP 上使用 xpath命名空间(不工作..)
在对 SO 和谷歌进行了几个小时的研究之后......我希望在这里得到一些帮助: (我距离运行正则表达式以完全删除名称空间仅一步之遥)
首先这是 XML:
<?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header xmlns="http://webservices.site.com/definitions">
<SessionId>0119A|1</SessionId>
</soap:Header>
<soap:Body>
<Security_AuthenticateReply xmlns="http://xml.site.com/QQ">
<processStatus>
<statusCode>P</statusCode>
</processStatus>
</Security_AuthenticateReply>
</soap:Body>
</soap:Envelope>
现在这是我的 PHP 代码:
$response = simplexml_load_string( $str ,NULL,
false, "http://schemas.xmlsoap.org/soap/envelope/" );
// just making sure the name space is "registered"
// but I tested all examples also with this removed
$response->registerXPathNamespace("soap",
"http://schemas.xmlsoap.org/soap/envelope/");
$_res = $response->xpath('//soap:Header');
print_r($_res);
/*** result: simple query for the root "soap" namespace, this looks good! (so far..)
Array
(
[0] => SimpleXMLElement Object
(
[SessionId] => 0119A|1
)
)
***/
// now we query for the "SessionId" element in the XML
$_res = $response->xpath('//soap:Header/SessionId');
print_r($_res);
/*** result: this does not return anything!
Array
(
)
***/
// another approach
$_res = $response->xpath('//soap:Header/SessionId/text()');
print_r($_res);
/*** result: this does not return anything at all!
***/
// Finally, without using XPath this does work
$_res = $response->xpath('//soap:Header');
$_res = (string)$_res[0]->SessionId;
echo $_res;
/*** result: this worked
0119A|1
***/
如何使用 XPATH 获取 SOAP 消息???
谢谢, 罗马
After researching this on SO and google for hours now... I hope to get some help here:
(I am just one step away from running a regex to remove the namespaces completely)
First this is the XML:
<?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header xmlns="http://webservices.site.com/definitions">
<SessionId>0119A|1</SessionId>
</soap:Header>
<soap:Body>
<Security_AuthenticateReply xmlns="http://xml.site.com/QQ">
<processStatus>
<statusCode>P</statusCode>
</processStatus>
</Security_AuthenticateReply>
</soap:Body>
</soap:Envelope>
Now this is what my code in PHP looks like:
$response = simplexml_load_string( $str ,NULL,
false, "http://schemas.xmlsoap.org/soap/envelope/" );
// just making sure the name space is "registered"
// but I tested all examples also with this removed
$response->registerXPathNamespace("soap",
"http://schemas.xmlsoap.org/soap/envelope/");
$_res = $response->xpath('//soap:Header');
print_r($_res);
/*** result: simple query for the root "soap" namespace, this looks good! (so far..)
Array
(
[0] => SimpleXMLElement Object
(
[SessionId] => 0119A|1
)
)
***/
// now we query for the "SessionId" element in the XML
$_res = $response->xpath('//soap:Header/SessionId');
print_r($_res);
/*** result: this does not return anything!
Array
(
)
***/
// another approach
$_res = $response->xpath('//soap:Header/SessionId/text()');
print_r($_res);
/*** result: this does not return anything at all!
***/
// Finally, without using XPath this does work
$_res = $response->xpath('//soap:Header');
$_res = (string)$_res[0]->SessionId;
echo $_res;
/*** result: this worked
0119A|1
***/
How can I get the SOAP message working with XPATH???
Thanks,
Roman
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
多个命名空间弄乱了它,添加以下内容
也适合我,请参阅 这个之前的堆栈溢出问题
The multiple namespaces are messing with it, adding the following works for me
also, see this previous stack overflow question
您还需要注册
元素使用的默认命名空间。因为
位于默认命名空间中,所以它没有任何前缀,但为了让您的 XPath 正常工作,您还需要将此命名空间绑定到某个前缀,然后在您的 XPath 中使用该前缀表达。不带命名空间前缀的 XPath (1.0) 表达式始终仅与无命名空间中的目标匹配。
You need to register the default namespace used by
<SessionId>
element as well. Because<SessionId>
is in the default namespace it does not have any prefix but in order to your XPath to work, you need to bind also this namespace to some prefix and then use that prefix in your XPath expression.XPath (1.0) expressions without a namespace prefix always match only to targets in no-namespace.