2011-05-22 148 views
84

我一直在試圖解析HTML5代碼,所以我可以在代碼中設置屬性/值,但似乎DOMDocument(PHP5.3)不支持<nav>這樣的標籤和<section>關於html5標籤的PHP DOMDocument錯誤/警告

有沒有什麼辦法可以將它解析爲HTML中的HTML並操作代碼?


代碼重現:

<?php 
$dom = new DOMDocument(); 
$dom->loadHTML("<!DOCTYPE HTML> 
<html><head><title>test</title></head> 
<body> 
<nav> 
    <ul> 
    <li>first 
    <li>second 
    </ul> 
</nav> 
<section> 
    ... 
</section> 
</body> 
</html>"); 

錯誤

Warning: DOMDocument::loadHTML(): Tag nav invalid in Entity, line: 4 in /home/wbkrnl/public_html/new-mvc/1.php on line 17

Warning: DOMDocument::loadHTML(): Tag section invalid in Entity, line: 10 in /home/wbkrnl/public_html/new-mvc/1.php on line 17

+0

行動,爲我'loadHTML(HTML5 $)'返回FALSE(失敗)!我需要將新標籤更改爲DIV ......這不僅是我屏幕上的「警告」問題。 – 2014-02-03 21:22:19

+1

此問題已在https://bugs.php.net/bug上針對PHP進行報告。php?id = 60021然後在基礎libxml2中產生一個功能請求:https://bugzilla.gnome.org/show_bug.cgi?id = 761534 – cweiske 2016-02-04 07:57:01

回答

136

沒有,沒有指定特定的doctype使用或者修改的要求的方式現有的。

你最好的可行的解決方案將是禁用錯誤與libxml_use_internal_errors報告:

$dom = new DOMDocument; 
libxml_use_internal_errors(true); 
$dom->loadHTML('...'); 
libxml_clear_errors(); 
+1

OPS,對於我'loadHTML($ HTML5)'返回FALSE(失敗)!我需要將新標籤更改爲DIV ... – 2014-02-03 21:22:38

+0

真棒,非常感謝您的答案和@Klaas感謝您的問題。 – whitesiroi 2016-06-27 08:43:08

+5

任何原因__ * php7 * __內置的DOM解析器_still_無法處理HTML5?答覆提交已經6年了。 – 2017-07-01 21:44:39

7

你也可以做

@$dom->loadHTML($htmlString); 
+11

錯誤抑制不是處理此問題的正確方法。 – 2014-09-12 09:55:52

+4

@ KlaasSangers直到我們有一個非殘缺的DOM實現,恐怕是(通過'@'或'libxml_ *') – Dan 2014-09-18 20:56:58

+5

是的,在這個特定的情況下,在我看來,錯誤抑制是最好的解決方案。除非你知道你將要加載的HTML,按照PHP的定義,它應該是100%有效的HTML。根據我的經驗,這絕不是這種情況。 – hanshenrik 2015-02-21 08:38:16

5

您可以過濾你從解析器得到錯誤。按其他的答案在這裏,錯誤報告關閉屏幕,然後通過誤差迭代,並只顯示你想要的:

libxml_use_internal_errors(TRUE); 
// Do your load here 
$errors = libxml_get_errors(); 

foreach ($errors as $error) 
{ 
    /* @var $error LibXMLError */ 
} 

這是一個錯誤的print_r()

LibXMLError Object 
(
    [level] => 2 
    [code] => 801 
    [column] => 17 
    [message] => Tag section invalid 

    [file] => 
    [line] => 39 
) 

通過匹配message和/或code,這些可以很容易地過濾掉。

1

這爲我工作:

$html = file_get_contents($url); 

$search = array("<header>", "</header>", "<nav>", "</nav>", "<section>", "</section>"); 
$replace = array("<div>", "</div>","<div>", "</div>", "<div>", "</div>"); 
$html = str_replace($search, $replace, $html); 

$dom = new DOMDocument(); 
$dom->loadHTML($html); 

如果您需要的標題標記,用div標籤更改標題和使用的ID。例如:

$search = array("<header>", "</header>"); 
$replace = array("<div id='header1'>", "</div>"); 

這不是最好的解決方案,但取決於具體情況它可能有用。

祝你好運。

-3

HTML5標籤幾乎總是使用id,class等屬性。所以替換的代碼將是:

$html = file_get_contents($url); 
$search = array(
    "<header", "</header>", 
    "<nav", "</nav>", 
    "<section", "</section>", 
    "<article", "</article>", 
    "<footer", "</footer>", 
    "<aside", "</aside>", 
    "<noindex", "</noindex>", 
); 
$replace = array(
    "<div", "</div>", 
    "<div", "</div>", 
    "<div", "</div>", 
    "<div", "</div>", 
    "<div", "</div>", 
    "<div", "</div>", 
    "<div", "</div>", 
); 
$html = str_replace($search, $replace, $html); 
$dom = new DOMDocument(); 
$dom->loadHTML($html); 
0

似乎沒有辦法殺死警告,但沒有錯誤。 PHP具有應該這樣做的常量,但它們似乎不起作用。這裏是什麼是應該工作,但不會因爲(錯誤?)......

$doc=new DOMDocument(); 
$doc->loadHTML("<tagthatdoesnotexist><h1>Hi</h1></tagthatdoesnotexist>", LIBXML_NOWARNING); 
echo $doc->saveHTML(); 

http://php.net/manual/en/libxml.constants.php

+0

這是一個固定的錯誤:https://bugs.php.net/bug.php?id = 74004 – 2017-10-09 09:28:32

+0

根據這個帖子https://stackoverflow.com/a/41845049/937477錯誤已被修復 – 2017-10-09 09:34:40