更新:html5lib
(问题的底部)似乎已经接近了,我只需要提高对其使用方式的理解。
我正在尝试为PHP 5.3找到兼容HTML5的DOM解析器。特别是,我需要在脚本标记中访问以下类似HTML的CDATA:
<script type="text/x-jquery-tmpl" id="foo">
<table><tr><td>${name}</td></tr></table>
</script>
大多数解析器会在{4.0} </
标记内找到ETAGO(<script>
)时因为HTML 4.01 ends script tag parsing而过早解析。但是,</script>
之前的HTML5 allows for </
。到目前为止,我尝试过的所有解析器都失败了,或者它们的文档记录很差,以至于我还没弄清楚它们是否有效。
我的要求:
输入:
<script id="foo"><td>bar</td></script>
输出失败的示例(无结束</td>
):
<script id="foo"><td>bar</script>
一些解析器及其结果:
来源:
<?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>
来源:
<?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>
来源:
<?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>
可能很有希望。我可以查看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>
答案 0 :(得分:10)
我遇到了同样的问题,显然你可以通过将文档加载为XML来破解你的方式,并将其保存为HTML:)
$d = new DOMDocument;
$d->loadXML('<script id="foo"><td>bar</td></script>');
echo $d->saveHTML();
但当然,标记必须没有错误才能使loadXML正常工作。
答案 1 :(得分:5)
Re:html5lib
点击下载标签和download the PHP version of the parser。
您解压缩本地文件夹中的存档
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
您更改目录并创建名为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
解析器将解析文档树,并返回一个DOMDocument对象,该对象可以像任何其他DOMDocument对象一样进行操作。
答案 2 :(得分:5)
FluentDOM使用DOMDocument但阻止加载通知和警告。它没有自己的解析器。您可以添加自己的加载器(例如,使用html5lib的加载器)。
答案 3 :(得分:4)
我在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');
});
});
不理想,但我不确定是否有更好的解决方法。
答案 4 :(得分:3)
我遇到了这个问题。
PHP Dom Document解析脚本标记内的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);
我希望这会对某些人有所帮助: - )。