Анализ 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> <requestContactResponse xmlns="http://webservice.foo.com"> <requestContactReturn> <errorCode xsi:nil="true"/> <errorDesc xsi:nil="true"/> <id>744</id> </requestContactReturn> </requestContactResponse> </soapenv:Body> </soapenv:Envelope> 

В частности, я хочу получить значение тега <id>

Вот что я пробовал:

 $dom = new DOMDocument; $dom->loadXML($xml); $dom->children('soapenv', true)->Envelope->children('soapenv', true)->Body->children()->requestContactResponse->requestContactReturn->id; 

Но я получаю сообщение об ошибке:

PHP Неустранимая ошибка: вызов неопределенного метода DOMDocument :: children ()

Я также пытался использовать simpleXML:

 $sxe = new SimpleXMLElement($xml); $sxe->children('soapenv', true)->Envelope->children('soapenv', true)->Body->children()->requestContactResponse->requestContactReturn->id; 

Но я получаю это другое сообщение об ошибке:

PHP Неустранимая ошибка: вызов функции-члена children () на не-объекте

Последнее решение, которое я пробовал:

 $sxe = new SimpleXMLElement($xml); $elements = $sxe->children("soapenv", true)->Body->requestContactResponse->requestContactReturn; foreach($elements as $element) { echo "|-$element->id-|"; } 

На этот раз сообщение об ошибке было:

 Invalid argument supplied for foreach() 

Какие-либо предложения?

Плохо документированный факт заключается в том, что, когда вы выбираете пространство имен с ->children , оно остается в силе для дочерних узлов .

Поэтому, когда вы запрашиваете $sxe->children("soapenv", true)->Body->requestContactResponse requestContactResponse, SimpleXML предполагает, что вы все еще говорите о пространстве имен "soapenv" , так что ищет элемент <soapenv:requestContactResponse> , который не существует.

Чтобы вернуться к пространству имен по умолчанию, вам нужно снова вызвать ->children , с пространством имен NULL :

 $sx->children("soapenv", true)->Body->children(NULL)->requestContactResponse->requestContactReturn->id