Обновление: html5lib
(внизу вопроса), похоже, близко, мне просто нужно улучшить свое понимание того, как оно используется.
Я пытаюсь найти HTML-совместимый парсер DOM для PHP 5.3. В частности, мне нужно получить доступ к следующему HTML-подобному CDATA в теге script:
<script type="text/x-jquery-tmpl" id="foo">
<table><tr><td>${name}</td></tr></table>
</script>
Большинство парсеров перестанут разбираться преждевременно, потому что HTML 4.01 завершает script разбор тегов, когда он находит ETAGO (</
) внутри тега <script>
. Тем не менее, HTML5 позволяет </
до </script>
. Все парсеры, которые я пробовал до сих пор, либо потерпели неудачу, либо они настолько плохо документированы, что я не понял, работают ли они или нет.
Мои требования:
- Реальный парсер, а не регулярные выражения.
- Возможность загрузки полных страниц или фрагментов HTML.
- Возможность вытащить содержимое script, выбрав атрибут идентификатора тега.
Input:
<script id="foo"><td>bar</td></script>
Пример выхода с ошибкой (без закрытия </td>
):
<script id="foo"><td>bar</script>
Некоторые парсеры и их результаты:
DOMDocument (сбой)
Источник:
<?php
header('Content-type: text/plain');
$d = new DOMDocument;
$d->loadHTML('<script id="foo"><td>bar</td></script>');
echo $d->saveHTML();
Вывод:
Warning: DOMDocument::loadHTML(): Unexpected end tag : td in Entity, line: 1 in /home/adam/public_html/2010/10/26/dom.php on line 5
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><head><script id="foo"><td>bar</script></head></html>
FluentDOM (сбой)
Источник:
<?php
header('Content-type: text/plain');
require_once 'FluentDOM/src/FluentDOM.php';
$html = "<html><head></head><body><script id='foo'><td></td></script></body></html>";
echo FluentDOM($html, 'text/html');
Вывод:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><head></head><body><script id="foo"><td></script></body></html>
phpQuery (сбой)
Источник:
<?php
header('Content-type: text/plain');
require_once 'phpQuery.php';
phpQuery::newDocumentHTML(<<<EOF
<script type="text/x-jquery-tmpl" id="foo">
<td>test</td>
</script>
EOF
);
echo (string) pq ('# foo');
Вывод:
<script type="text/x-jquery-tmpl" id="foo">
<td>test
</script>
html5lib (проходит)
Возможно многообещающий. Могу ли я получить содержимое тега script#foo
?
Источник:
<?php
header('Content-type: text/plain');
include 'HTML5/Parser.php';
$html = "<!DOCTYPE html><html><head></head><body><script id='foo'><td></td></script></body></html>";
$d = HTML5_Parser::parse($html);
echo $d->saveHTML();
Вывод:
<html><head></head><body><script id="foo"><td></td></script></body></html>