DOMparsing器,允许使用HTML5风格的</ in <script>标记
更新 : html5lib
(问题的底部)似乎接近,我只需要提高我的理解如何使用。
我正在尝试为PHP 5.3find一个兼容HTML5的DOMparsing器。 特别是,我需要在脚本标记中访问以下类似HTML的CDATA:
<script type="text/x-jquery-tmpl" id="foo"> <table><tr><td>${name}</td></tr></table> </script>
大多数parsing器会提前parsing,因为HTML 4.01在<script>
标签内findETAGO( </
)时会结束脚本标签parsing 。 但是,HTML5 允许在</script>
之前。 到目前为止我所尝试过的所有parsing器都没有成功,或者它们的logging太差,以至于我没有弄清楚它们是否工作。
我的要求:
- 真正的parsing器,而不是正则expression式黑客。
- 能够加载完整页面或HTML片段。
- 能够拉出脚本内容 ,通过标签的id属性进行select。
input:
<script id="foo"><td>bar</td></script>
输出失败的示例(不结束</td>
):
<script id="foo"><td>bar</script>
一些parsing器及其结果:
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>
我有同样的问题,显然你可以通过加载文件为XML,并保存为HTML :)来破解你的方式
$d = new DOMDocument; $d->loadXML('<script id="foo"><td>bar</td></script>'); echo $d->saveHTML();
但是,当然,标记必须是无错误的loadXML工作。
Re:html5lib
您点击下载选项卡并下载parsing器的PHP版本 。
您解压本地文件夹中的存档
tar -zxvf html5lib-php-0.1.tar.gz x html5lib-php-0.1/ x html5lib-php-0.1/VERSION x html5lib-php-0.1/docs/ ... etc
您更改目录并创build一个名为hello.php的文件
cd html5lib-php-0.1 touch hello.php
您将以下PHP代码放在hello.php
$html = '<html><head></head><body> <script type="text/x-jquery-tmpl" id="foo"> <table><tr><td>${name}</td></tr></table> </script> </body></html>'; $dom = HTML5_Parser::parse($html); var_dump($dom->saveXml()); echo "\nDone\n";
你从命令行运行hello.php
php hello.php
parsing器将parsing文档树,并返回一个DOMDocument对象,该对象可以像任何其他DOMDocument对象一样进行操作。
FluentDOM使用DOMDocument,但阻止加载通知和警告。 它没有自己的parsing器。 你可以添加你自己的装载器(例如使用html5lib)。
我在我的jQuery模板块(CDATA块也失败了)中添加了注释标记( <!-- ... -->
),并且DOMDocument没有触及内部HTML。
然后,在我使用jQuery模板之前,我写了一个脚本来删除注释。
$(function() { $('script[type="text/x-jquery-tmpl"]').text(function() { // The comment node in this context is actually a text node. return $.trim($(this).text()).replace(/^<!--([\s\S]*)-->$/, '$1'); }); });
不理想,但我不确定更好的解决方法。
我遇到了这个确切的问题。
PHP Dom文档parsing脚本标签内的html,实际上可以导致一个完全不同的dom。
因为我不想使用DomDocument以外的其他库。 我写了几行删除任何脚本内容,然后你做任何你需要做的dom文件,然后你把这个脚本内容回来。
显然脚本内容不可用于您的dom对象,因为它是空的。
用以下的PHP代码行,你可以“修复”这个问题。 被警告脚本标签中的脚本标签会导致错误。
$scripts = array(); // this will select all script tags non-greedy. If you have a script tag in your script tag, it will cause problems. preg_match_all("/((<script.*>)(.*))\/script>/sU", $html, $scripts); // Make content of scripts empty $html = str_replace($scripts[3], '', $html); // Do DOM Document stuff here // Put script contents back $html = str_replace($scripts[2], $scripts[1], $html);
我希望这会帮助一些人:-)。