Предложить правильный подход для анализа недопустимого ответа xml с пространствами имен в этом случае

Я использую php для анализа xml ответа API. Вот пример ответа

 $xml = '<?xml version="1.0"?> <q:response xmlns:q="http://api-url"> <q:impression> <q:content> <html> <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://api-response-url/with/lots?of=parameters&somethingmore=someval" width="320px" height="50px" style="border:none;"></iframe> </body> </html> </q:content> <q:cpc>0.02</q:cpc> </q:impression> </q:response>'; 

Обратите внимание на следующие моменты:

В ответе есть некорректная разметка вроде этого –

  • <head> tag start внутри <html> нет, но он закрыт.
  • Теги <meta> внутри <html> не закрыты.
  • Атрибут src iframe содержит URL с несколькими параметрами, разделенными символом & . Таким образом, этот и любые другие возможные URL-адреса должны быть ранжированы до $dom->loadXML(); (см. мой код ниже).

требование

  • Мне нужно прочитать все, что есть внутри тегов <q:content></q:content> .
  • Мне нужно разобрать недопустимую разметку (как я понимаю) и правильно прочитать содержимое.
  • url необходимо закодировать для символов, как указано в разделе Какие символы мне нужно бежать в документах XML? , Это необходимо сделать с текущей логикой, которой я следую.

Текущий код

Итак, далеко у меня есть этот код, который отлично работает, если содержимое внутри тегов <q:content></q:content> является допустимой разметкой –

 $dom = new DOMDocument; $dom->loadXML($xml); // load the XML string defined above - works only if entire xml is valid $adHtml = ""; foreach ($dom->getElementsByTagNameNS('http://api-url', '*') as $element) { if($element->localName == "content") { $children = $element->childNodes; foreach ($children as $child) { $adHtml .= $child->ownerDocument->saveXML($child); } } } echo $adHtml; //Have got necessary contents here 

Проверьте рабочий код здесь (с действительной разметкой и одним параметром в iframe src).

Что я сейчас думаю

Теперь, перейдя к решению, данному @hakre в моем предыдущем вопросе –

  • Я попытался с DOMDocument::loadHTML() и он DOMDocument::loadHTML() неудачу, как я ожидал. Предоставляет предупреждения: – Warning: DOMDocument::loadHTML(): Tag q:response invalid in Entity, line: 2

  • вывести определенную часть строки для символов, перечисленных в разделе Какие символы мне нужно удалить в документах XML? ,

Вопрос

Наконец, если мне нужно «избежать определенной части строки» (в моем случае ищите все, что есть между <q:content></q:content> ), как указано в этом ответе на urlencode, что бы там ни было, то почему бы мне не искать эти разделители ( <q:content></q:content> ) в первую очередь и вернуть их? Тогда в чем преимущество использования DOMDocument::loadXML() в таких случаях? Я думаю, это довольно распространенный случай …

Итак, на мой вопрос дается это Требование и пункты, приведенные в Примечании, следующие пункты: – что является самым умным способом?

При внедрении стандарта можно сделать много действительных вариантов. Тем не менее, не существует правильного выбора в нарушении стандарта. Вам нужно предоставить тем, кто отправляет вам эти данные, некоторые из их действительных вариантов при внедрении стандарта XML.

Одним из таких вариантов было бы размещение содержимого HTML в CDATA . Другим было бы кодирование HTML.

Для них просто неприемлемо отправлять вам мусор и называть его XML. Возможно, они не понимают, что это неправда XML, но это просто нет. Если они вам не верят, вам следует просто попытаться открыть «XML» в стандартном XML-редакторе, таком как XMLspy. Пусть они обращаются к XMLspy как к третьей стороне, которая может сказать им, является ли их XML действительным.

Затем они могут свободно выбирать, как создавать допустимый XML, и вам придется решать их выбор.