PHP DOMDocument hataları / html5 etiketlerindeki uyarılar


105

HTML5 kodunu ayrıştırmaya çalışıyorum, böylece kodun içindeki öznitelikleri / değerleri ayarlayabilirim, ancak DOMDocument (PHP5.3) <nav>ve gibi etiketleri desteklemiyor gibi görünüyor <section>.

Bunu PHP'de HTML olarak ayrıştırmanın ve kodu değiştirmenin bir yolu var mı?


Çoğaltılacak kod:

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

Hata

Uyarı: DOMDocument :: loadHTML (): Varlık'ta etiket nav geçersiz, satır: /home/wbkrnl/public_html/new-mvc/1.php satır 17'de

Uyarı: DOMDocument :: loadHTML (): Varlık'ta etiket bölümü geçersiz, satır: /home/wbkrnl/public_html/new-mvc/1.php satır 17'de 10


Ops, benim için loadHTML($HTML5)YANLIŞ (başarısızlık) döndürüyor! Yeni etiketleri DIV olarak değiştirmem gerekiyor ... Bu sadece ekranımdaki "uyarılar" sorunu değil.
Peter Krauss

2
Bu sorun PHP için bugs.php.net/bug.php?id=60021 adresinde bildirilmiş ve bu da temeldeki libxml2'de bir özellik isteği
doğurmuştur

Yanıtlar:


193

Hayır, kullanmak için belirli bir belge türü belirtmenin veya mevcut olanın gereksinimlerini değiştirmenin bir yolu yoktur.

Uygulanabilir en iyi çözümünüz, aşağıdakilerle hata raporlamayı devre dışı bırakmak olacaktır libxml_use_internal_errors:

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

1
Ops, benim için loadHTML($HTML5)YANLIŞ (başarısızlık) döndürüyor! Yeni etiketleri DIV olarak değiştirmem gerekiyor ...
Peter Krauss

21
Php7'nin yerleşik DOM ayrıştırıcısının HTML5'i hala işleyememesinin bir nedeni var mı? Bu cevabın gönderilmesinin üzerinden 6 yıl geçti.
Super Cat

1
@SuperCat Hepsi temeldeki libxml kitaplığına bağlıdır.
lonesomeday

6
--- HTML5'in XML olmadığından bahsetmiyorum bile, hiç olmadı, olmadı ve olmayacak ...
Kevin_Kinsey

2
2019 Güncellemesi : Uyarı hala tetikleniyor, ancak loadHTMLartık gerçekten HTML5 etiketlerini kabul ediyor.

9

Sen de yapabilirsin

@$dom->loadHTML($htmlString);

16
Hata bastırma, bu sorunu çözmenin uygun bir yolu değildir.
Klaas Sangers

6
@KlaasSangers Sakat bırakılmamış bir DOM uygulamasına sahip olana kadar, korkarım (üzerinden @veya libxml_*)
Dan Lugg

6
evet, bu özel durumda, bence en iyi çözüm hata bastırmadır. Yükleyeceğiniz HTML'nin PHP'nin tanımına göre% 100 geçerli HTML olması gerektiğini bilmediğiniz sürece. benim deneyimime göre asla böyle değildir.
hanshenrik

@KlaasSangers ... neden olmasın?
Nick Manning

PHP8 "@ operatörü artık ölümcül hataları susturmuyor Bu değişikliğin PHP 8'den önce gizlenen hataları ortaya çıkarması mümkündür. Üretim sunucularınızda display_errors = Off ayarını yaptığınızdan emin olun!" Stitcher.io/blog/new-in-php-8
marcus

7

Ayrıştırıcıdan aldığınız hataları filtreleyebilirsiniz. Buradaki diğer yanıtlarda olduğu gibi, ekrana hata bildirimini kapatın ve ardından hataları yineleyin ve yalnızca istediklerinizi gösterin:

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

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

İşte print_r()tek bir hata:

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

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

messageVe / veya üzerinde eşleştirerek code, bunlar oldukça kolay bir şekilde filtrelenebilir.


2

Uyarıları ortadan kaldırmanın bir yolu yok gibi görünüyor ama hataları yok. PHP'nin bunu yapması gereken sabitler vardır, ancak bunlar çalışmıyor gibi görünüyor. İşte çalışması GEREKEN, ama çalışmayan çünkü (hata?) ....

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

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


Bu gönderiye göre stackoverflow.com/a/41845049/937477 bu hata düzeltildi
mmmmm 9'17

1
Bilgiçlik taslamak için, bu geçerli HTML5 değil. Özel öğelerin içinde w3c.github.io/webcomponents/spec/custom/…
Greg

@Greg Bilmekte fayda var. Bu sadece xml ayrıştırıcısının etiketin geçerli olmadığını anlayacağını, ancak bayrak nedeniyle onu yok sayacağını göstermek için yapılan bir testtir.
user2782001

0

Bu benim için çalıştı:

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

Başlık etiketine ihtiyacınız varsa, başlığı bir div etiketiyle değiştirin ve bir kimlik kullanın. Örneğin:

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

En iyi çözüm değil, ancak duruma bağlı olarak faydalı olabilir.

İyi şanslar.


-5

HTML5 etiketleri neredeyse her zaman id, class vb. Gibi öznitelikleri kullanır. Dolayısıyla, değiştirme kodu şöyle olacaktır:

$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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.