PHP DOMDocument Fehler / Warnungen auf HTML5-Tags

105

Ich habe versucht, HTML5-Code zu analysieren, damit ich Attribute / Werte innerhalb des Codes festlegen kann, aber es scheint, dass DOMDocument (PHP5.3) Tags wie <nav>und nicht unterstützt <section>.

Gibt es eine Möglichkeit, dies als HTML in PHP zu analysieren und den Code zu manipulieren?


Zu reproduzierender Code:

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

Error

Warnung: DOMDocument :: loadHTML (): Tag nav in Entity ungültig, Zeile: 4 in /home/wbkrnl/public_html/new-mvc/1.php in Zeile 17

Warnung: DOMDocument :: loadHTML (): Tag-Abschnitt in Entität ungültig, Zeile: 10 in /home/wbkrnl/public_html/new-mvc/1.php in Zeile 17

Klaas Sangers
quelle
Ops, für mich loadHTML($HTML5)gibt FALSE (Fehler) zurück! Ich muss die neuen Tags in DIVs ändern ... Es ist nicht nur ein Problem von "Warnungen" auf meinem Bildschirm.
Peter Krauss
2
Dieses Problem wurde für PHP unter bugs.php.net/bug.php?id=60021 gemeldet, was wiederum eine Funktionsanforderung in der zugrunde liegenden libxml2 hervorrief
cweiske

Antworten:

193

Nein, es gibt keine Möglichkeit, einen bestimmten zu verwendenden Doctype anzugeben oder die Anforderungen des vorhandenen zu ändern.

Ihre beste praktikable Lösung besteht darin, die Fehlerberichterstattung zu deaktivieren mit libxml_use_internal_errors:

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML('...');
libxml_clear_errors();
einsamer Tag
quelle
1
Ops, für mich loadHTML($HTML5)gibt FALSE (Fehler) zurück! Ich muss die neuen Tags in DIVs ändern ...
Peter Krauss
21
Gibt es einen Grund , warum der in php7 integrierte DOM-Parser HTML5 immer noch nicht verarbeiten kann? Es ist 6 Jahre her, seit diese Antwort eingereicht wurde.
Super Cat
1
@ SuperCat Es hängt alles von der zugrunde liegenden libxml-Bibliothek ab.
einsamer
6
---
Ganz
2
Update 2019 : Die Warnung wird weiterhin ausgelöst, loadHTMLakzeptiert jedoch jetzt tatsächlich HTML5-Tags.
9

Sie könnten auch tun

@$dom->loadHTML($htmlString);
Ilker Mutlu
quelle
16
Die Fehlerunterdrückung ist keine geeignete Methode, um dieses Problem zu beheben.
Klaas Sangers
6
@KlaasSangers Bis wir eine nicht verkrüppelte DOM-Implementierung haben, fürchte ich, dass es (entweder durch @oder libxml_*) ist
Dan Lugg
6
Ja, in diesem speziellen Fall ist die Fehlerunterdrückung meiner Meinung nach die beste Lösung. Wenn Sie nicht wissen, dass der HTML-Code, den Sie laden, 100% gültiger HTML-Code gemäß der PHP-Definition sein soll. was meiner Erfahrung nach nie der Fall ist.
Hanshenrik
@KlaasSangers ... warum nicht?
Nick Manning
PHP8 "Der @ -Operator bringt schwerwiegende Fehler nicht mehr zum Schweigen Es ist möglich, dass diese Änderung Fehler aufdeckt, die vor PHP 8 erneut ausgeblendet wurden. Stellen Sie sicher, dass display_errors = Off auf Ihren Produktionsservern deaktiviert ist!" stitcher.io/blog/new-in-php-8
marcus
7

Sie können die Fehler filtern, die Sie vom Parser erhalten. Deaktivieren Sie gemäß den anderen Antworten hier die Fehlerberichterstattung auf dem Bildschirm, durchlaufen Sie die Fehler und zeigen Sie nur die gewünschten an:

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

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

Hier ist print_r()ein einzelner Fehler:

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

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

Durch Matching auf dem messageund / oder dem codekönnen diese ganz einfach herausgefiltert werden.

halfer
quelle
2

Es scheint keine Möglichkeit zu geben, Warnungen zu töten, aber keine Fehler. PHP hat Konstanten, die dies tun sollen, aber sie scheinen nicht zu funktionieren. Hier ist, was funktionieren sollte, aber nicht, weil (Fehler?) ....

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

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

user2782001
quelle
Laut diesem Beitrag stackoverflow.com/a/41845049/937477 wurde dieser Fehler behoben
mmmmm
1
Nur um pedantisch zu sein, das ist kein gültiges HTML5. Benutzerdefinierte Elemente müssen einen Bindestrich gemäß der Spezifikation w3c.github.io/webcomponents/spec/custom/… enthalten
Greg
@ Greg Gut zu wissen. Es ist nur ein Test, um zu demonstrieren, dass der XML-Parser erkennt, dass das Tag ungültig ist, aber es aufgrund des Flags ignoriert.
user2782001
0

Das hat bei mir funktioniert:

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

Wenn Sie das Header-Tag benötigen, ändern Sie den Header durch ein div-Tag und verwenden Sie eine ID. Zum Beispiel:

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

Es ist nicht die beste Lösung, aber je nach Situation kann es nützlich sein.

Viel Glück.

Emiliano Sangoi
quelle
-5

HTML5-Tags verwenden fast immer Attribute wie ID, Klasse usw. Der Code zum Ersetzen lautet also:

$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);
Sergey Kaluzhsky
quelle