PHP DOMДокументальні помилки / попередження на html5-тегах


105

Я намагався проаналізувати 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 недійсний в Entity, рядок: 4 в /home/wbkrnl/public_html/new-mvc/1.php у рядку 17

Попередження: DOMDocument :: loadHTML (): розділ тегів недійсний в Entity, рядок: 10 в /home/wbkrnl/public_html/new-mvc/1.php у рядку 17


Ой, для мене loadHTML($HTML5)повертається ФАЛЬ (помилка)! Мені потрібно змінити нові теги на DIV ... Це не лише проблема "попереджень" на моєму екрані.
Пітер Краус

2
Про цю проблему повідомлялося для PHP за адресою bugs.php.net/bug.php?id=60021, яка, в свою чергу, породила запит на функцію в базовій libxml2: bugzilla.gnome.org/show_bug.cgi?id=761534
cweiske

Відповіді:


193

Ні, не існує способу конкретизації конкретного доктрипу для використання чи зміни вимог існуючого.

Вашим найкращим ефективним рішенням буде відключити повідомлення про помилки за допомогою libxml_use_internal_errors:

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

1
Ой, для мене loadHTML($HTML5)повертається ФАЛЬ (помилка)! Мені потрібно змінити нові теги на DIVs ...
Пітер Краус

21
З будь-якої причини вбудований аналізатор php7 в DOM все ще не може обробити HTML5? З моменту подання цієї відповіді минуло 6 років.
Супер Кіт

1
@SuperCat Все залежить від основної бібліотеки libxml.
самотній день

6
--- не кажучи вже про HTML5 - це не XML, ніколи не було, не було, не буде ...
Kevin_Kinsey

2
Оновлення 2019 : Попередження все ще діє, однак loadHTMLтепер фактично приймають теги HTML5.

9

Ви також можете зробити

@$dom->loadHTML($htmlString);

16
Помилка помилок не є належним способом вирішення цього питання.
Клаас Санджерс

6
@KlaasSangers Доки у нас не буде покалічена реалізація DOM, я боюся, що це (або через, @або libxml_*)
Dan Lugg

6
так, у цьому конкретному випадку придушення помилок є найкращим рішенням, на мою думку. якщо ви не знаєте, що HTML, який ви завантажуєте, повинен бути 100% дійсним HTML за визначенням PHP. що, з мого досвіду, ніколи не буває.
hanshenrik

@KlaasSangers ... чому б і ні?
Нік Меннінг

PHP8 "Оператор @ більше не замовчує фатальні помилки. Можливо, що ця зміна може виявити помилки, які знову були приховані перед PHP 8. Обов'язково встановіть display_errors = Вимкнено на виробничих серверах!" stitcher.io/blog/new-in-php-8
березня

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/en/libxml.constants.php


Відповідно до цього повідомлення stackoverflow.com/a/41845049/937477 ця помилка була виправлена
mmmmm

1
Просто для педантичності, це неправда HTML5. Спеціальні елементи повинні мати дефіс у відповідності зі специфікацією w3c.github.io/webcomponents/spec/custom/…
Грег

@Greg Добре знати. Це просто тест, щоб продемонструвати, що XML-аналізатор визнає тег недійсним, але ігнорує його через прапор.
користувач2782001

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 та використовуйте ідентифікатор. Наприклад:

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

Це не найкраще рішення, але залежно від ситуації воно може бути корисним.

Удачі.


-5

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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.