DOM解析器,允许HTML5样式的</ in <script>标记

Ann*_*rom 48 php html5 dom

更新 :( html5lib问题的底部)似乎接近,我只需要提高我对它如何使用的理解.

我正在尝试为PHP 5.3找到兼容HTML5的DOM解析器.特别是,我需要在脚本标记中访问以下类似HTML的CDATA:

<script type="text/x-jquery-tmpl" id="foo">
    <table><tr><td>${name}</td></tr></table>
</script>
Run Code Online (Sandbox Code Playgroud)

大多数解析器都会过早地解析,因为HTML 4.01 在标记</内部找到ETAGO()时会结束脚本标记解析<script>.但是,HTML5 允许</之前</script>.到目前为止,我尝试过的所有解析器都失败了,或者它们的文档记录很差,以至于我还没弄清楚它们是否有效.

我的要求:

  1. 真正的解析器,而不是正则表达式.
  2. 能够加载整页或HTML片段.
  3. 能够将脚本内容拉回,通过标签的id属性进行选择.

输入:

<script id="foo"><td>bar</td></script>
Run Code Online (Sandbox Code Playgroud)

输出失败的示例(无关闭</td>):

<script id="foo"><td>bar</script>
Run Code Online (Sandbox Code Playgroud)

一些解析器及其结果:


DOMDocument(失败)

资源:

<?php

header('Content-type: text/plain');
$d = new DOMDocument;
$d->loadHTML('<script id="foo"><td>bar</td></script>');
echo $d->saveHTML();
Run Code Online (Sandbox Code Playgroud)

输出:

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>
Run Code Online (Sandbox Code Playgroud)


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');
Run Code Online (Sandbox Code Playgroud)

输出:

<!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>
Run Code Online (Sandbox Code Playgroud)


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
);
Run Code Online (Sandbox Code Playgroud)

echo(string)pq('#foo');

输出:

<script type="text/x-jquery-tmpl" id="foo">
<td>test
</script>
Run Code Online (Sandbox Code Playgroud)


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();
Run Code Online (Sandbox Code Playgroud)

输出:

<html><head></head><body><script id="foo"><td></td></script></body></html>
Run Code Online (Sandbox Code Playgroud)

Ale*_*lex 11

我有同样的问题,显然你可以通过将文档加载为XML来破解你的方式,并将其保存为HTML :)

$d = new DOMDocument;
$d->loadXML('<script id="foo"><td>bar</td></script>');
echo $d->saveHTML();
Run Code Online (Sandbox Code Playgroud)

但是当然,标记必须没有错误才能使loadXML正常工作.


小智 7

我刚刚发现(就我而言)。

尝试更改loadHTML使用LIBXML_SCHEMA_CREATE的参数选项DOMDocument

$dom = new DOMDocument;

libxml_use_internal_errors(true);
//$dom->loadHTML($buffer, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$dom->loadHTML($buffer, LIBXML_SCHEMA_CREATE);
Run Code Online (Sandbox Code Playgroud)


Ala*_*orm 5

Re:html5lib

单击下载选项卡并下载解析器的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
Run Code Online (Sandbox Code Playgroud)

您更改目录并创建名为hello.php的文件

cd html5lib-php-0.1
touch hello.php 
Run Code Online (Sandbox Code Playgroud)

您将以下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";
Run Code Online (Sandbox Code Playgroud)

您运行hello.php命令行

php hello.php
Run Code Online (Sandbox Code Playgroud)

解析器将解析文档树,并返回一个DOMDocument对象,该对象可以像任何其他DOMDocument对象一样进行操作.


ThW*_*ThW 5

FluentDOM使用DOMDocument但阻止加载通知和警告.它没有自己的解析器.您可以添加自己的加载器(例如,使用html5lib的加载器).