У меня проблема при разборе HTML с PHP DOMDocument.
Разбор HMTL, который я обрабатываю, имеет следующий тег script:
<script type="text/javascript">
var showShareBarUI_params_e81 =
{
buttonWithCountTemplate: '<div class="sBtnWrap"><a href="#" onclick="$onClick"><div class="sBtn">$text<img src="$iconImg" /></div><div class="sCountBox">$count</div></a></div>',
}
</script>
Этот фрагмент имеет две проблемы:
1) HTML внутри buttonWithCountTemplate
var не экранирован. DOMDocument управляет этим правильно, избегая символов при его разборе. Не проблема.
2) В конце есть тег img с неэкранированным закрывающим тегом:
<img src="$iconImg" />
/>
заставляет DOMDocument считать, что script закончен, но ему не хватает закрывающего тега. Если вы извлечете script с помощью getElementByTagName, вы получите тег закрытым в этом теге img, а остальные будут выглядеть как текст в HTML.
Моя цель - удалить все скрипты на этой странице, поэтому, если я делаю removeChild()
по этому тегу, тэг удаляется, а следующая часть отображается как текст при рендеринге страницы:
</div><div class="sCountBox">$count</div></a></div>',
}
</script>
Фиксация HTML не является решением, потому что я разрабатываю общий синтаксический анализатор и должен обрабатывать все типы HTML.
Мой вопрос в том, должен ли я делать какую-либо дезинфекцию перед подачей HTML в DOMDocument или если в DOMDocument есть опция включить эту проблему, даже если я могу удалить все теги перед загрузкой HTML.
Любые идеи?
ИЗМЕНИТЬ
После некоторых исследований я обнаружил реальную проблему парсера DOMDocument. Рассмотрим следующий HTML:
<div> <!-- Offending div without closing tag -->
<script type="text/javascript">
var test = '</div>';
// I should not appear on the result
</script>
Используя следующий PHP-код для удаления тегов script (на основе ответа Голизаде):
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
libxml_use_internal_errors(true);
$dom->loadHTML(file_get_contents('js.html'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
//@$dom->loadHTMLFile('script.html'); //fix tags if not exist
while($nodes = $dom->getElementsByTagName("script")) {
if($nodes->length == 0) break;
$script = $nodes->item(0);
$script->parentNode->removeChild($script);
}
//return $dom->saveHTML();
$final = $dom->saveHTML();
echo $final;
Результат будет следующим:
<div> <!-- Offending div without closing tag -->
<p>';
// I should not appear on the result
</p></div>
Проблема заключается в том, что первый тег div не закрыт и кажется, что DOMDocument принимает теги div внутри строки JS как html вместо простой строки JS.
Что я могу сделать, чтобы решить эту проблему? Помните, что изменение HTML не является вариантом, так как я разрабатываю общий парсер.