PHP DOMDocument lỗi / cảnh báo trên thẻ html5


105

Tôi đã cố gắng phân tích cú pháp mã HTML5 để có thể đặt thuộc tính / giá trị trong mã, nhưng có vẻ như DOMDocument (PHP5.3) không hỗ trợ các thẻ như <nav><section>.

Có cách nào để phân tích cú pháp này như HTML trong PHP và thao tác mã không?


Mã để tái tạo:

<?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>");

lỗi

Cảnh báo: DOMDocument :: loadHTML (): Điều hướng thẻ không hợp lệ trong Thực thể, dòng: 4 trong /home/wbkrnl/public_html/new-mvc/1.php trên dòng 17

Cảnh báo: DOMDocument :: loadHTML (): Phần thẻ không hợp lệ trong Thực thể, dòng: 10 trong /home/wbkrnl/public_html/new-mvc/1.php trên dòng 17


Ops, đối với tôi loadHTML($HTML5)trả về FALSE (thất bại)! Tôi cần thay đổi các thẻ mới thành DIV ... Đó không chỉ là vấn đề "cảnh báo" trên màn hình của tôi.
Peter Krauss

2
Sự cố này đã được báo cáo cho PHP tại bug.php.net/bug.php?id=60021 , từ đó sinh ra một yêu cầu tính năng trong libxml2 cơ bản: bugzilla.gnome.org/show_bug.cgi?id=761534
cweiske

Câu trả lời:


193

Không, không có cách nào chỉ định một loại tài liệu cụ thể để sử dụng hoặc sửa đổi các yêu cầu của loại tài liệu hiện có.

Giải pháp khả thi tốt nhất của bạn sẽ là vô hiệu hóa báo cáo lỗi với libxml_use_internal_errors:

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

1
Ops, đối với tôi loadHTML($HTML5)trả về FALSE (thất bại)! Tôi cần phải thay đổi các thẻ mới để DIV ...
Peter Krauss

21
Bất kỳ lý do nào mà trình phân tích cú pháp DOM tích hợp sẵn của php7 vẫn không thể xử lý HTML5? Đã 6 năm kể từ khi câu trả lời này được gửi.
Super Cat,

1
@SuperCat Tất cả đều phụ thuộc vào thư viện libxml bên dưới.
một

6
--- chưa kể đến HTML5 không XML, không bao giờ là, đã được, cũng không phải sẽ là ...
Kevin_Kinsey

2
Cập nhật năm 2019 : Cảnh báo vẫn được kích hoạt nhưng loadHTMLgiờ đây thực sự chấp nhận các thẻ HTML5.

9

Bạn cũng có thể làm

@$dom->loadHTML($htmlString);

16
Ngăn chặn lỗi không phải là một cách thích hợp để giải quyết vấn đề này.
Klaas Sangers

6
@KlaasSangers Cho đến khi chúng tôi có một thi DOM không tê liệt, tôi sợ nó là (hoặc thông qua @hay libxml_*)
Dan lugg

6
vâng, trong trường hợp cụ thể này, theo tôi, khắc phục lỗi là giải pháp tốt nhất. trừ khi bạn biết rằng HTML bạn sẽ tải, được cho là HTML hợp lệ 100% theo định nghĩa của PHP. mà theo kinh nghiệm của tôi, không bao giờ đúng như vậy.
hanshenrik

@KlaasSangers ... tại sao không?
Nick Manning

PHP8 "Toán tử @ không còn tắt tiếng các lỗi nghiêm trọng Có thể thay đổi này có thể tiết lộ các lỗi đã được ẩn trước PHP 8. Hãy đảm bảo đặt display_errors = Tắt trên máy chủ sản xuất của bạn!" stiren.io/blog/new-in-php-8
marcus

7

Bạn có thể lọc các lỗi bạn nhận được từ trình phân tích cú pháp. Theo các câu trả lời khác ở đây, hãy tắt báo cáo lỗi trên màn hình, sau đó lặp lại các lỗi và chỉ hiển thị những lỗi bạn muốn:

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

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

Đây là một print_r()lỗi duy nhất:

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

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

Bằng cách đối sánh trên messagevà / hoặc code, chúng có thể được lọc ra khá dễ dàng.


2

Dường như không có cách nào để loại bỏ các cảnh báo mà không phải là lỗi. PHP có các hằng số được cho là để làm điều này, nhưng chúng dường như không hoạt động. Đây là những gì NÊN làm việc, nhưng không phải vì (lỗi?) ....

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

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


Theo bài này stackoverflow.com/a/41845049/937477 rằng lỗi đã được cố định
mmmmm

1
Nói một cách phức tạp, đó không phải là HTML5 hợp lệ. Các phần tử tùy chỉnh phải có dấu gạch nối theo thông số w3c.github.io/webcomponents/spec/custom/…
Greg

@Greg Tốt để biết. Đây chỉ là một bài kiểm tra để chứng minh trình phân tích cú pháp xml sẽ nhận ra thẻ không hợp lệ, nhưng hãy bỏ qua nó vì cờ.
dùng2782001

0

Điều này đã làm việc cho tôi:

$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);

Nếu bạn cần thẻ tiêu đề, hãy thay đổi tiêu đề bằng thẻ div và sử dụng id. Ví dụ:

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

Nó không phải là giải pháp tốt nhất nhưng tùy thuộc vào tình huống mà nó có thể hữu ích.

Chúc may mắn.


-5

Các thẻ HTML5 hầu như luôn sử dụng các thuộc tính như id, class, v.v. Vì vậy, mã để thay thế sẽ là:

$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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.