Tengo un código HTML donde hay atributos como @click , @autocomplete:change usado por algunas bibliotecas JS.
Cuando analizo el HTML usando DOMDocument, estos atributos se eliminan.
Código de muestra:
<?php $content = <<<'EOT' <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head></head> <body> <a role="tab" @click="activeType=listingType"></a> <input type="text" @autocomplete:change="handleAutocomplete"> </body> </html> EOT; // creating new document $doc = new DOMDocument('1.0', 'utf-8'); $doc->recover = true; $doc->strictErrorChecking = false; //turning off some errors libxml_use_internal_errors(true); // it loads the content without adding enclosing html/body tags and also the doctype declaration $doc->LoadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); echo $doc->saveHTML(); ?>Producción:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head></head> <body> <a role="tab"></a> <input type="text"> </body> </html>Si no hay forma de hacer que DOMDocument acepte @ en los nombres de los atributos, podemos reemplazar @ con una cadena especial antes de loadHTML() y volver a reemplazar después de saveHTML()
<?php $content = <<<'EOT' <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head></head> <body> <a role="tab" @click="activeType=listingType"></a> <input type="text" @autocomplete:change="handleAutocomplete"> </body> </html> EOT; // creating new document $doc = new DOMDocument('1.0', 'utf-8'); $doc->recover = true; $doc->strictErrorChecking = false; //turning off some errors libxml_use_internal_errors(true); $content = str_replace('@', 'at------', $content); // it loads the content without adding enclosing html/body tags and also the doctype declaration $doc->LoadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $html = $doc->saveHTML(); $html = str_replace('at------', '@', $html); echo $html;producción:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head></head> <body> <a role="tab" @click="activeType=listingType"></a> <input type="text" @autocomplete:change="handleAutocomplete"> </body> </html> Y reemplace @click con at-click y @autocomplete con at-autocomplete .
# this is a PHP 8 example class MyDomDocument extends DomDocument { private $replace = [ '@click'=>'at-click', '@autocomplete'=>'at-autocomplete' ]; public function loadHTML(string $content, int $options = 0) { $content = str_replace(array_keys($this->replace), array_values($this->replace), $content); return parent::loadHTML($content, $options); } #[\ReturnTypeWillChange] public function saveHTML(?DOMNode $node = null) { $content = parent::saveHTML($node); $content = str_replace(array_values($this->replace), array_keys($this->replace), $content); return $content; } } $content = <<<'EOT' <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head></head> <body> <a role="tab" @click="activeType=listingType"></a> <input type="text" @autocomplete:change="handleAutocomplete"> </body> </html> EOT; $dom = new MyDomDocument(); $dom->loadHTML($content); var_dump($dom->getElementsByTagName('a')[0]->getAttribute('at-click')); var_dump($dom->getElementsByTagName('input')[0]->getAttribute('at-autocomplete:change')); echo $dom->saveHTML(); <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head></head> <body> <a role="tab" @click="activeType=listingType"></a> <input type="text" @autocomplete:change="handleAutocomplete"> </body> </html>