HTML5 태그의 PHP DOMDocument 오류 / 경고


105

나는 코드 내에서 속성 / 값을 설정할 수 있도록 내가 구문 분석 HTML5 코드를 시도했습니다,하지만있는 DOMDocument (PHP5.3가)와 같은 태그를 지원하지 않는 것 같습니다 <nav><section>.

이것을 PHP에서 HTML로 구문 분석하고 코드를 조작하는 방법이 있습니까?


재현 할 코드 :

<?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 () : 엔티티에서 잘못된 태그 탐색, 줄 : 17 줄의 /home/wbkrnl/public_html/new-mvc/1.php의 4

경고 : DOMDocument :: loadHTML () : 엔티티에서 잘못된 태그 섹션, 줄 : 17 줄의 /home/wbkrnl/public_html/new-mvc/1.php의 10


Ops, 나를 위해 loadHTML($HTML5)FALSE (실패)를 반환합니다! 새 태그를 DIV로 변경해야합니다 ... 내 화면의 "경고"문제 만이 아닙니다.
Peter Krauss 2014

2
이 문제는 bugs.php.net/bug.php?id=60021 에서 PHP에 대해보고되었으며 기본 libxml2 : bugzilla.gnome.org/show_bug.cgi?id=761534
cweiske

답변:


193

아니요, 사용할 특정 doctype을 지정하거나 기존 문서 유형의 요구 사항을 수정할 방법이 없습니다.

가장 효과적인 해결책은 다음을 사용하여 오류보고를 비활성화하는 것입니다 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
php7 의 내장 DOM 파서가 여전히 HTML5를 처리 할 수없는 이유 는 무엇입니까? 이 답변이 제출 된 지 6 년이되었습니다.
Super Cat

1
@SuperCat 그것은 모두 기본 libxml 라이브러리에 의존합니다.
lonesomeday

6
--- ... HTML5가없는 XML했다 적이있다한다 말할 것도없고 될 것 없다
Kevin_Kinsey

2
업데이트 2019 : 경고는 여전히 발생하지만 loadHTML이제 실제로 HTML5 태그를 허용합니다.

9

당신은 또한 할 수 있습니다

@$dom->loadHTML($htmlString);

16
오류 억제는이 문제를 처리하는 적절한 방법이 아닙니다.
Klaas Sangers 2014 년

6
우리는 비 파행 DOM 구현을 할 때까지 @KlaasSangers, 나는 (중 하나를 통해 그것이 두려워 @libxml_*)
댄 Lugg

6
예,이 특정 경우에는 오류 억제가 최선의 해결책이라고 생각합니다. 로드 할 HTML을 알지 못한다면 PHP 정의에 따라 100 % 유효한 HTML이어야합니다. 내 경험으로는 결코 그렇지 않습니다.
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에는이를 수행해야하는 상수가 있지만 작동하지 않는 것 같습니다. 다음은 SHOULD가 작동하지만 (버그?) ...

 $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

@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, 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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.