Я использую 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>
тега начала внутри <html>
нет, но он закрыт.
<meta>
теги внутри <html>
не закрыты.
- Атрибут iframe
src
содержит 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()
, и это не удалось, как я ожидал. Предупреждает, как - Warning: DOMDocument::loadHTML(): Tag q:response invalid in Entity, line: 2
экранировать определенную часть строки для символов, перечисленных в Какие символы мне нужно экранировать в документах XML? .
Вопрос
Наконец, если мне нужно «экранировать определенную часть строки» (в моем случае ищите все, что находится между <q:content></q:content>
), как указано в этом ответе, для urlencode, что бы там ни было, то почему бы не Я в первую очередь ищу те разделители (<q:content></q:content>
) и возвращаю это? Тогда какая польза от использования DOMDocument::loadXML()
в таких случаях? Я думаю, это довольно распространенный случай ...
Итак, мой вопрос задается этим Требованием и баллами, указанными в Обратите внимание на следующие моменты - , какой самый умный способ продолжить?