Использование xpath для объекта PHP SimpleXML, пространства имен SOAP + (не работает..)

После изучения этого в SO и Google в течение нескольких часов... Я надеюсь получить здесь некоторую помощь: (я всего в одном шаге от запуска регулярного выражения, чтобы полностью удалить пространства имен)

Сначала это 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
***/

Как я могу заставить сообщение SOAP работать с XPATH???

Спасибо, Роман


person Community    schedule 05.10.2010    source источник
comment
Проще всего было бы использовать DOM вместо SimpleXml, но я думаю, что это не вариант?   -  person Gordon    schedule 05.10.2010
comment
Я обнаружил, что при изменении этой части XML: ‹soap:Header xmlns=webservices.site.com/definitions› Кому: ‹soap:Header› Упомянутые запросы Xpath начинают работать. Есть какие-нибудь мысли по этому поводу? плохой формат XML??   -  person    schedule 05.10.2010


Ответы (2)


Несколько пространств имен возятся с ним, добавляя для меня следующие работы

$response->registerXPathNamespace("site", "http://webservices.site.com/definitions");
$_res = $response->xpath('//site:SessionId');

также см. этот предыдущий вопрос о переполнении стека.

person Dave    schedule 05.10.2010
comment
Оба ответа были хорошими, так как вы были быстрее (на одну минуту), я выбрал его как правильный ответ :) - person ; 05.10.2010

Вам также необходимо зарегистрировать пространство имен по умолчанию, используемое элементом <SessionId>. Поскольку <SessionId> находится в пространстве имен по умолчанию, у него нет префикса, но для того, чтобы ваш XPath работал, вам также необходимо привязать это пространство имен к некоторому префиксу, а затем использовать этот префикс в вашем выражении XPath.

$response->registerXPathNamespace("ns",
    "http://webservices.site.com/definitions");
$_res = $response->xpath('//soap:Header/ns:SessionId');

Выражения XPath (1.0) без префикса пространства имен всегда соответствуют только целям без пространства имен.

person jasso    schedule 05.10.2010