Parser DOM que permite a tag </ in de estilo HTML5

Atualização : html5lib (parte inferior da pergunta) parece chegar perto, eu só preciso aprimorar minha compreensão sobre como ele é usado.

Estou tentando encontrar um analisador de HTML compatível com HTML5 para PHP 5.3. Em particular, eu preciso acessar o seguinte CDATA tipo HTML em uma tag de script:

  
${name}

A maioria dos analisadores finalizará a análise prematuramente porque o HTML 4.01 termina a análise do label do script quando ele encontra o ETAGO ( </ ) dentro de uma marca . No entanto, HTML5 permite </ before . Todos os analisadores que tentei até agora falharam, ou estão tão mal documentados que não descobri que funcionam ou não.

Meus requisitos:

  1. Parser real, não regex hacks.
  2. Capacidade de carregar páginas completas ou fragments HTML.
  3. Capacidade de retirar o conteúdo do script de volta, selecionando pelo atributo id da tag.

Entrada:

 bar 

Exemplo de saída em falha (sem fechamento

):

 bar 

Alguns analisadores e seus resultados:

DOMDocument (falha)

Fonte:

 loadHTML('bar'); echo $d->saveHTML(); 

Saída:

 Warning: DOMDocument::loadHTML(): Unexpected end tag : td in Entity, line: 1 in /home/adam/public_html/2010/10/26/dom.php on line 5  bar 

FluentDOM (falha)

Fonte:

 <?php header('Content-type: text/plain'); require_once 'FluentDOM/src/FluentDOM.php'; $html = ""; echo FluentDOM($html, 'text/html'); 

Saída:

   

phpQuery (falha)

Fonte:

 <?php header('Content-type: text/plain'); require_once 'phpQuery.php'; phpQuery::newDocumentHTML(<<<EOF  test  EOF ); 

echo (string) pq (‘# foo’);

Saída:

  test  

html5lib (passa)

Possivelmente promissor. Posso obter o conteúdo do script#foo tag?

Fonte:

 <?php header('Content-type: text/plain'); include 'HTML5/Parser.php'; $html = ""; $d = HTML5_Parser::parse($html); echo $d->saveHTML(); 

Saída:

  

Eu tive o mesmo problema e, aparentemente, você pode cortar seu caminho através deste carregando o documento como XML e salvá-lo como HTML 🙂

 $d = new DOMDocument; $d->loadXML(''); echo $d->saveHTML(); 

Mas é claro que a marcação deve ser livre de erros para que o loadXML funcione.

Re: html5lib

Você clica na guia de download e baixa a versão do PHP do analisador .

Você desencadeia o arquivo em uma pasta local

  tar -zxvf html5lib-php-0.1.tar.gz x html5lib-php-0.1/ x html5lib-php-0.1/VERSION x html5lib-php-0.1/docs/ ... etc 

Você altera diretórios e cria um arquivo chamado hello.php

 cd html5lib-php-0.1 touch hello.php 

Você coloca o seguinte código PHP em hello.php

 $html = '  '; $dom = HTML5_Parser::parse($html); var_dump($dom->saveXml()); echo "\nDone\n"; 

Você executar o hello.php partir da linha de comando

 php hello.php 

O analisador analisará a tree de documentos e retornará um object DOMDocument, que pode ser manipulado como qualquer outro object DOMDocument.

O FluentDOM usa o DOMDocument, mas bloqueia o carregamento de avisos e avisos. Não possui um analisador próprio. Você pode adicionar seus próprios carregadores (por exemplo, um que usa o html5lib).

Eu adicionei tags de comentário ( ) nos blocos de modelo jQuery (os blocos CDATA também falharam) eo DOMDocument não tocou no HTML interno.

Então, antes de usar os modelos jQuery, escrevi um script para remover os comentários.

 $(function() { $('script[type="text/x-jquery-tmpl"]').text(function() { // The comment node in this context is actually a text node. return $.trim($(this).text()).replace(/^$/, '$1'); }); }); 

Não era ideal, mas não tinha certeza de uma solução melhor.

Eu corri para esse problema exato.

O Documento do PHP Dom analisa o html dentro de uma tag de script e isso pode realmente levar a uma dom completamente diferente.

Como não queria usar outra biblioteca do que o DomDocument. Eu escrevi algumas linhas que tira todo o conteúdo do script, então você faz o que você precisa fazer com o documento dom e depois você colocou o conteúdo desse script de volta.

Obviamente, o conteúdo do script não está disponível para o seu object dom porque está vazio.

Com as seguintes linhas de código php, você pode “consertar” esse problema. Esteja avisado que as tags de script nas tags de scripts causarão erro.

 $scripts = array(); // this will select all script tags non-greedy. If you have a script tag in your script tag, it will cause problems. preg_match_all("/(( 

Espero que isso ajude algumas pessoas :-).