ข้อผิดพลาด PHP DOMDocument / คำเตือนบนแท็ก html5


107

ฉันได้รับการพยายามที่จะแยก HTML5 รหัสเพื่อให้สามารถตั้งค่าแอตทริบิวต์ / ค่าภายในรหัส แต่ดูเหมือนว่า DOMDocument (PHP5.3) ไม่สนับสนุนแท็กเช่นและ<nav><section>

มีวิธีใดบ้างในการแยกวิเคราะห์สิ่งนี้เป็น HTML ใน PHP และจัดการโค้ด


รหัสที่จะทำซ้ำ:

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

ข้อผิดพลาด

คำเตือน: DOMDocument :: loadHTML (): แท็ก nav ไม่ถูกต้องในเอนทิตีบรรทัด: 4 ใน /home/wbkrnl/public_html/new-mvc/1.php ในบรรทัดที่ 17

คำเตือน: DOMDocument :: loadHTML (): ส่วนแท็กไม่ถูกต้องในเอนทิตีบรรทัด: 10 ใน /home/wbkrnl/public_html/new-mvc/1.php ในบรรทัดที่ 17


Ops สำหรับฉันloadHTML($HTML5)คืนค่า FALSE (ความล้มเหลว)! ฉันต้องเปลี่ยนแท็กใหม่เป็น DIV ... ไม่ใช่แค่ปัญหา "คำเตือน" บนหน้าจอของฉัน
Peter Krauss

2
ปัญหานี้ได้รับการรายงานสำหรับ PHP ที่bugs.php.net/bug.php?id=60021ซึ่งจะทำให้เกิดคำขอคุณลักษณะใน libxml2: bugzilla.gnome.org/show_bug.cgi?id=761534
cweiske

คำตอบ:


194

ไม่ไม่มีวิธีการระบุประเภทเฉพาะที่จะใช้หรือแก้ไขข้อกำหนดของหลักที่มีอยู่

ทางออกที่ดีที่สุดของคุณคือปิดการใช้งานการรายงานข้อผิดพลาดด้วยlibxml_use_internal_errors:

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

1
Ops สำหรับฉันloadHTML($HTML5)คืนค่า FALSE (ความล้มเหลว)! ฉันต้องการเปลี่ยนแท็กใหม่เป็น DIV ...
Peter Krauss

21
เหตุผลใดที่ตัวแยกวิเคราะห์ DOM ในตัวของphp7ยังไม่สามารถจัดการ HTML5 ได้ เป็นเวลา 6 ปีแล้วที่มีการส่งคำตอบนี้
Super Cat

1
@SuperCat ทุกอย่างขึ้นอยู่กับไลบรารี libxml พื้นฐาน
lonesomeday

6
--- ไม่ต้องพูดถึง HTML5 ไม่ใช่ XML ไม่เคยเป็นมาก่อนและจะไม่เป็น ...
Kevin_Kinsey

2
อัปเดต 2019 : คำเตือนยังคงทำงานอยู่ แต่loadHTMLตอนนี้ยอมรับแท็ก HTML5 แล้ว

10

คุณยังสามารถทำได้

@$dom->loadHTML($htmlString);

17
การระงับข้อผิดพลาดไม่ใช่วิธีที่เหมาะสมในการจัดการกับปัญหานี้
Klaas Sangers

6
@KlaasSangers จนกว่าเราจะมีการใช้งาน DOM ที่ไม่พิการฉันกลัวว่าจะเป็นเช่นนั้น (ผ่าน@หรือlibxml_*)
Dan Lugg

6
ใช่ในกรณีเฉพาะนี้การบีบอัดข้อผิดพลาดเป็นทางออกที่ดีที่สุดในความคิดของฉัน เว้นแต่คุณจะทราบว่า HTML ที่คุณจะโหลดควรเป็น HTML ที่ถูกต้อง 100% ตามคำจำกัดความของ PHP ซึ่งจากประสบการณ์ของฉันไม่เคยเป็นเช่นนั้น
hanshenrik

@KlaasSangers ... ทำไมไม่?
Nick Manning

PHP8 "ตัวดำเนินการ @ ไม่ปิดเสียงข้อผิดพลาดร้ายแรงอีกต่อไปเป็นไปได้ว่าการเปลี่ยนแปลงนี้อาจเปิดเผยข้อผิดพลาดที่ซ่อนอยู่ก่อน PHP 8 อีกครั้งอย่าลืมตั้งค่า display_errors = Off บนเซิร์ฟเวอร์การผลิตของคุณ!" stitcher.io/blog/new-in-php-8
marcus

7

คุณสามารถกรองข้อผิดพลาดที่คุณได้รับจากโปรแกรมแยกวิเคราะห์ ตามคำตอบอื่น ๆ ที่นี่ให้ปิดการรายงานข้อผิดพลาดไปยังหน้าจอจากนั้นทำซ้ำข้อผิดพลาดและแสดงเฉพาะสิ่งที่คุณต้องการ:

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เหล่านี้สามารถกรองออกได้ค่อนข้างง่าย


2

ดูเหมือนจะไม่มีวิธีฆ่าคำเตือน แต่ไม่ใช่ข้อผิดพลาด PHP มีค่าคงที่ที่ควรทำ แต่ดูเหมือนจะไม่ได้ผล นี่คือสิ่งที่ควรใช้งานได้ แต่ทำไม่ได้เพราะ (บั๊ก?) ....

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

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


ตามโพสต์นี้stackoverflow.com/a/41845049/937477ข้อบกพร่องนั้นได้รับการแก้ไขแล้ว
mmmmm

1
เพื่อเป็นการอวดดีนั่นไม่ใช่ HTML5 ที่ถูกต้อง องค์ประกอบที่กำหนดเองต้องมียัติภังค์อยู่ในนั้นตามข้อกำหนดw3c.github.io/webcomponents/spec/custom/…
Greg

@Greg สิ่งที่ควรรู้ เป็นเพียงการทดสอบเพื่อแสดงให้เห็นว่าโปรแกรมแยกวิเคราะห์ xml จะรับรู้ว่าแท็กไม่ถูกต้อง แต่ไม่ต้องสนใจเนื่องจากแฟล็ก
user2782001

0

สิ่งนี้ใช้ได้ผลสำหรับฉัน:

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

ไม่ใช่ทางออกที่ดีที่สุด แต่ขึ้นอยู่กับสถานการณ์ที่สามารถเป็นประโยชน์ได้

โชคดี.


-5

แท็ก HTML5 มักจะใช้แอตทริบิวต์เช่น id คลาสเป็นต้น ดังนั้นรหัสสำหรับการแทนที่จะเป็น:

$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);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.