我希望能够加载任何
HTML文档并使用php的domdocument功能进行编辑.
问题是,某些网站(例如facebook)会在其标签中添加
XML样式的命名空间.
<fb:like send="true" width="450" show_faces="true"></fb:like>
DOMDocument对脏代码非常宽容,但它不接受html代码中的namescpaces.会发生什么:
>如果我使用loadHTML加载代码,名称空间将被剥离,但我需要它留下来
>如果我使用loadXML加载代码,我将收到大量错误,表明我没有加载有效的XML
所以我的想法是将我得到的HTML转换为XML,以便我可以使用loadXML解析它.我的问题是,我该怎么做,我应该使用哪个工具(我听说Tidy但是我无法使它工作)或者使用不同的解析器(一个可以在html中处理命名空间的解析器)更好的主意码)
代码段:
<?php
$html = file_get_contents($_POST['url']);
$domDoc = new DOMDocument();
$domDoc->loadHTML($html);
//Just do anything here. It doesn't matter what. For example I'm deleting the head tag
$headTag = $domDoc->getElementsByTagName("head")->item(0);
$headTagParent = $headTag->parentNode;
$headTagParent->removeChild($headTag);
echo $domDoc->saveHTML();
//This will work as expected for any url EXCEPT the ones that use XML namespaces like facebook does as described above. In case of such dirty coding the namespace will get deleted by DOMDocument
?>
最佳答案 没有干净的方法使用DOMDocument解析HTML与命名空间而不会丢失命名空间,但有一些解决方法:
>使用另一个接受HMTL代码中的命名空间的解析器.查看here以获取HTML解析器的详细列表.这可能是最有效的方法.
>如果你想坚持使用DOMDocument,你基本上必须对代码进行预处理和后处理.
>在将代码发送到DOMDocument-> loadHTML之前,请使用正则表达式,循环或任何您想要查找所有命名空间标记的内容,并将自定义属性添加到包含命名空间的开始标记.
<fb:like send="true" width="450" show_faces="true"></fb:like>
然后会导致
<fb:like xmlNamespace="fb" send="true" width="450" show_faces="true"></fb:like>
>现在将编辑后的代码提供给DOMDocument-> loadHTML.它将删除命名空间,但它会保留导致的属性
<like xmlNamespace="fb" send="true" width="450" show_faces="true"></like>
>现在(再次使用正则表达式,循环或任何您想要的)查找具有属性xmlNamespace的所有标记,并将该属性替换为实际的名称空间.不要忘记将命名空间添加到结束标记!