문제

HTML과 유사한 레거시 문서가 많이 있습니다.마찬가지로 HTML처럼 보이지만 HTML의 일부가 아닌 추가 구성 태그가 있습니다.

<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>

이 파일들을 구문 분석해야 합니다.PHP는 사용 가능한 유일한 도구입니다.문서는 제대로 구성된 XML에 가깝지 않습니다.

내 원래 생각은 PHP DOMDocument에서 loadHTML 메서드를 사용하는 것이었습니다.그러나 이러한 방법은 구성 HTML 태그를 질식시키고 문자열/파일 구문 분석을 거부합니다.

$oDom = new DomDocument();
$oDom->loadHTML("<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>");
//gives us
DOMDocument::loadHTML() [function.loadHTML]: Tag pseud-template invalid in Entity, line: 1 occured in ....

내가 생각해 낼 수 있었던 유일한 해결책은 잘못된 태그를 제거하고 유효한 HTML 태그(태그 이름의 ID가 포함된 범위)로 바꾸는 문자열 교체 기능을 사용하여 파일을 사전 처리하는 것입니다.

더 우아한 솔루션이 있습니까?유효한 것으로 간주할 추가 태그에 대해 DOMDocument에 알리는 방법은 무엇입니까?PHP를 위한 다른 강력한 HTML 구문 분석 클래스/객체가 있습니까?

(명확하지 않다면 여기서는 정규식을 유효한 해결책으로 간주하지 않습니다)

업데이트:가짜 태그의 정보는 여기서 목표의 일부이므로 Tidy와 같은 것은 옵션이 아닙니다.또한 나는 전부는 아니더라도 어느 정도 수준의 잘 구성된 정리 작업을 수행하는 작업을 추구하고 있습니다. 이것이 바로 처음에 DomDocument의 loadHTML 메서드를 찾고 있던 이유입니다.

도움이 되었습니까?

해결책

다음을 사용하여 경고를 억제할 수 있습니다. libxml_use_internal_errors, 문서를 로드하는 동안.예:

libxml_use_internal_errors(true);
$doc = new DomDocument();
$doc->loadHTML("<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>");
libxml_use_internal_errors(false);

어떤 이유로 경고에 액세스해야 하는 경우 다음을 사용하세요. libxml_get_errors

다른 팁

"나쁜" HTML을 전달하는지 궁금합니다. HTML 깔끔한 첫 번째 패스로 도움이 될까요?문서를 올바른 형식으로 만들 수 있다면 DomDocument를 사용하여 일반 XML 파일로 로드할 수도 있습니다.

@twan 사용자 정의 XML을 구문 분석하기 위해 dtd가 필요하지 않습니다.그냥 사용 DOMDocument->load(), XML의 형식이 올바른 경우에는 읽을 수 있습니다.

파일의 형식이 올바르면 XML 파서를 살펴볼 수 있으며 그 전에 S.O.L이 됩니다.Lok Alejo는 이렇게 말했습니다. HTML 깔끔한, 그러나 이는 HTML에만 국한된 것으로 보이며 사용자 정의 요소와 어떻게 조화를 이룰지는 모르겠습니다.

여기서는 정규 표현식이 유효한 솔루션이라고 생각하지 않습니다.

당신이 올바른 형태를 갖추기 전까지는 이것이 유일한 선택일 수 있습니다.문서를 해당 단계로 가져오면 DOM 기능을 명확하게 사용할 수 있습니다.

PHP Fit 포트의 Parser를 살펴보세요.코드는 깨끗하며 원래 Word에서 저장한 더티 HTML을 로드하기 위해 설계되었습니다.테이블을 꺼내도록 구성되었지만 쉽게 조정할 수 있습니다.

여기에서 소스를 볼 수 있습니다:http://gerd.exit0.net/pat/PHPFIT/PHPFIT-0.1.0/Parser.phps

단위 테스트에서는 사용 방법을 보여줍니다.http://gerd.exit0.net/pat/PHPFIT/PHPFIT-0.1.0/test/parser.phps

이 문제에 대한 빠르고 더러운 해결책은 사용자 정의 태그 목록을 정규식과 일치시키는 루프를 실행하는 것이었습니다.정규식은 내부에 또 다른 사용자 정의 태그가 있는 태그를 포착하지 않습니다.

일치하는 항목이 있으면 해당 태그를 처리하는 함수가 호출되어 "처리된 HTML"을 반환합니다.해당 사용자 정의 태그가 상위 태그가 아닌 다른 사용자 정의 태그 안에 있는 경우 실제 HTML이 하위 태그 대신 삽입되었다는 사실로 인해 하위 태그가 없어지고 정규식에 의해 일치되어 루프의 다음 반복에서 처리됩니다.

일치하는 하위 항목이 없는 사용자 정의 태그가 없으면 루프가 종료됩니다.전반적으로 이는 반복적(while 루프)이며 재귀적이지 않습니다.

@앨런 스톰

내 다른 답변에 대한 귀하의 의견으로 인해 다음과 같은 생각이 들었습니다.

DOMDocument를 사용하여 HTML 파일을 로드하면 다음과 같은 일정 수준의 정리 작업을 수행하는 것으로 보입니다.잘 구성되어 있지만 모든 태그는 합법적인 HTML 태그여야 합니다.나는 전자를 수행하지만 후자는 수행하지 않는 것을 찾고 있습니다.(앨런 스톰)

태그에 대해 정규식(죄송합니다!)을 실행하고 유효한 HTML 요소가 아닌 요소를 찾으면 문서에 존재하지 않는 유효한 요소로 이를 대체합니다(blink 생각나네요...), 잘못된 요소의 이름과 함께 속성 값을 지정하여 나중에 다시 전환할 수 있도록 합니다.예:

$code = str_replace("<pseudo-tag>", "<blink rel=\"pseudo-tag\">", $code);
// and then back again...
$code = preg_replace('<blink rel="(.*?)">', '<\1>', $code);

분명히 그 코드는 작동하지 않을 것입니다. 하지만 일반적인 아이디어는 이해되시나요?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top