Невозможно разобрать XML-данные с двоеточием (:) из ответа с помощью getNamespaces ()

Я хочу прочитать все, что находится внутри тегов <q:content></q:content> в следующем xml

 $xml = '<?xml version="1.0"?> <q:response xmlns:q="http://api-url"> <q:impression> <q:content> <html> <head> <meta name="HandheldFriendly" content="True"> <meta name="viewport" content="width=device-width, user-scalable=no"> <meta http-equiv="cleartype" content="on"> </head> <body style="margin:0px;padding:0px;"> <iframe scrolling="no" src="http://some-url" width="320px" height="50px" style="border:none;"></iframe> </body> </html> </q:content> <q:cpc>0.02</q:cpc> </q:impression> ... ... some more things ... </q:response>'; 

Я поместил xml в переменную выше, а затем я использую SimpleXMLElement :: getNamespaces, как указано в разделе «Пример №1. Получаемые пространства имен документов» –

 //code continued $dom = new DOMDocument; // load the XML string defined above $dom->loadXML($xml); var_dump($dom->getElementsByTagNameNS('http://api-url', '*') ); // shows object(DOMNodeList)#3 (0) { } foreach ($dom->getElementsByTagNameNS('http://api-url', '*') as $element) { //this does not execute echo 'see - local name: ', $element->localName, ', prefix: ', $element->prefix, "\n"; } 

Но код внутри цикла for не выполняется.

Я прочитал эти вопросы –

  • PHP-скрипт не может читать xml-данные с помощью двоеточия (:)

  • Как читать тег <abc: xyz> xml с помощью php?

Обновить
Также попробовал это решение Parse XML с пространством имен с помощью SimpleXML –

 $xml = new SimpleXMLElement($xml); $xml->registerXPathNamespace('e', 'http://api-url'); foreach($xml->xpath('//e:q') as $event) { echo "not coming here"; $event->registerXPathNamespace('e', 'http://api-url'); var_export($event->xpath('//e:content')); } 

В этом случае код внутри foreach не выполняется. Не уверен, что все написано правильно …

Дальнейшее обновление
Начиная с первого решения … с error_reporting = -1, выяснилось, что проблема связана с URL-адресом в src attr тега iframe . Получение предупреждений –

 Warning: DOMDocument::loadXML(): EntityRef: expecting ';' in Entity, line: 13 

Обновленный код –

 $xml = '<?xml version="1.0"?> <q:response xmlns:q="http://api-url"> <q:impression> <q:content> <html> <head> <meta name="HandheldFriendly" content="True" /> <meta name="viewport" content="width=device-width, user-scalable=no" /> <meta http-equiv="cleartype" content="on" /> </head> <body style="margin:0px;padding:0px;"> <iframe scrolling="no" src="http://serve.qriously.com/v1/request?type=SERVE&aid=ratingtest&at=2&uid=0000000000000000&noHash=true&testmode=true&ua=Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1&appid=12e2561f048158249e30000012e256826ad&pv=2&rf=2&src=admarvel&type=get&lang=eng" width="320px" height="50px" style="border:none;"></iframe> </body> </html> </q:content> <q:cpc>0.02</q:cpc> </q:impression> <q:app_stats> <q:total><q:ctr>0.023809523809523808</q:ctr><q:ecpm>0.5952380952380952</q:ecpm></q:total> <q:today><q:ctr>0.043478260869565216</q:ctr><q:ecpm>1.0869565217391306</q:ecpm></q:today> </q:app_stats> </q:response>'; 

У меня нет проблем, чтобы заставить его работать, единственная ошибка, которую я могу найти, заключается в том, что вы загружаете XML, содержащий фрагмент HTML без XML, который нарушает документ: Мета элементы в разделе главы не закрыты.

См. Демонстрацию .

Совет. Всегда активируйте ведение журнала ошибок и отчетность, проверьте наличие предупреждений и уведомлений, если вы разрабатываете и отлаживаете код. Короткая однострочная строка, отображающая все сообщения об ошибках PHP, вкл. предупреждения , уведомления и строгие :

 error_reporting(-1); ini_set('display_errors', 1); 

DOMDocument является разговорчивым, а затем о некорректных элементах при загрузке XML.

Фиксация XML «на лету»

DomDocument принимает только действительный XML. Если у вас есть HTML, вы также можете попробовать, если DOMDocument::loadHTML() выполняет задание, но затем он преобразует загруженную строку в документ Х (HT) ML. Наверное, не то, что вы ищете.

Чтобы избежать определенной части строки для загрузки, чтобы сделать ее совместимой с XML, вы можете искать строковые шаблоны, чтобы получить подстроку, которая представляет HTML внутри XML и правильно закодировать XML.

Например, вы можете искать <html> и </html> в качестве окружающих тегов, извлекать подстроку целого и заменять ее на substr_replace() . Чтобы кодировать HTML для использования в качестве данных внутри XML, используйте htmlspecialchars() , она заменит все на пять сущностей в другом SO-ответе .

Некоторые макеты кода:

 $htmlStart = strpos($xml, '<html>'); if (false === $htmlStart) throw new Exception('<html> not found.'); $htmlEnd = strpos($xml, '</html>', $htmlStart); if (false === $htmlStart) throw new Exception('</html> not found.'); $htmlLen = $htmlEnd - $htmlStart + 7; $htmlString = substr($xml, $htmlStart, $htmlLen); $htmlEscaped = htmlspecialchars($htmlString, ENT_QUOTES); $xml = substr_replace($xml, $htmlEscaped, $htmlStart, $htmlLen);