with strip_tags remove quitar etiquetas ent_quotes eliminar php html dom html-parsing bbcode

php - remove - strip_tags mysql



Limpieza de HTML eliminando etiquetas de formato extra/redundantes (11)

Introducción

La mejor solución que se ha visto hasta ahora es usar HTML Tidy http://tidy.sourceforge.net/

Además de convertir el formato de un documento, Tidy también puede convertir etiquetas HTML en desuso en sus contrapartes de hoja de estilos en cascada (CSS) automáticamente mediante el uso de la opción de limpieza. El resultado generado contiene una declaración de estilo en línea.

También asegura que el documento HTML sea compatible con xhtml

Ejemplo

$code =''<p> <strong> <span style="font-size: 14px"> <span style="color: #006400"> <span style="font-size: 14px"> <span style="font-size: 16px"> <span style="color: #006400"> <span style="font-size: 14px"> <span style="font-size: 16px"> <span style="color: #006400">This is a </span> </span> </span> </span> </span> </span> </span> <span style="color: #006400"> <span style="font-size: 16px"> <span style="color: #b22222">Test</span> </span> </span> </span> </span> </strong> </p>'';

Si tu corres

$clean = cleaning($code); print($clean[''body'']);

Salida

<p> <strong> <span class="c3"> <span class="c1">This is a</span> <span class="c2">Test</span> </span> </strong> </p>

Puedes obtener el CSS

$clean = cleaning($code); print($clean[''style'']);

Salida

<style type="text/css"> span.c3 { font-size: 14px } span.c2 { color: #006400; font-size: 16px } span.c1 { color: #006400; font-size: 14px } </style>

Nuestro el HTML COMPLETO

$clean = cleaning($code); print($clean[''full'']);

Salida

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <style type="text/css"> /*<![CDATA[*/ span.c3 {font-size: 14px} span.c2 {color: #006400; font-size: 16px} span.c1 {color: #006400; font-size: 14px} /*]]>*/ </style> </head> <body> <p> <strong><span class="c3"><span class="c1">This is a</span> <span class="c2">Test</span></span></strong> </p> </body> </html>

Función utilizada

function cleaning($string, $tidyConfig = null) { $out = array (); $config = array ( ''indent'' => true, ''show-body-only'' => false, ''clean'' => true, ''output-xhtml'' => true, ''preserve-entities'' => true ); if ($tidyConfig == null) { $tidyConfig = &$config; } $tidy = new tidy (); $out [''full''] = $tidy->repairString ( $string, $tidyConfig, ''UTF8'' ); unset ( $tidy ); unset ( $tidyConfig ); $out [''body''] = preg_replace ( "/.*<body[^>]*>|<//body>.*/si", "", $out [''full''] ); $out [''style''] = ''<style type="text/css">'' . preg_replace ( "/.*<style[^>]*>|<//style>.*/si", "", $out [''full''] ) . ''</style>''; return ($out); }

=============================================

Edición 1: Hack sucio (no recomendado)

=============================================

En función de tu último comentario, es como si quisieras conservar el estilo de depreciación. Es posible que HTML Tidy no te permita hacer eso desde que se depreciated pero puedes hacerlo

$out = cleaning ( $code ); $getStyle = new css2string (); $getStyle->parseStr ( $out [''style''] ); $body = $out [''body'']; $search = array (); $replace = array (); foreach ( $getStyle->css as $key => $value ) { list ( $selector, $name ) = explode ( ".", $key ); $search [] = "<$selector class=/"$name/">"; $style = array (); foreach ( $value as $type => $att ) { $style [] = "$type:$att"; } $replace [] = "<$selector style=/"" . implode ( ";", $style ) . ";/">"; }

Salida

<p> <strong> <span style="font-size:14px;"> <span style="color:#006400;font-size:14px;">This is a</span> <span style="color:#006400;font-size:16px;">Test</span> </span> </strong> </p>

Clase utilizada

//Credit : http://stackoverflow.com/a/8511837/1226894 class css2string { var $css; function parseStr($string) { preg_match_all ( ''/(?ims)([a-z0-9, /s/./:#_/-@]+)/{([^/}]*)/}/'', $string, $arr ); $this->css = array (); foreach ( $arr [0] as $i => $x ) { $selector = trim ( $arr [1] [$i] ); $rules = explode ( '';'', trim ( $arr [2] [$i] ) ); $this->css [$selector] = array (); foreach ( $rules as $strRule ) { if (! empty ( $strRule )) { $rule = explode ( ":", $strRule ); $this->css [$selector] [trim ( $rule [0] )] = trim ( $rule [1] ); } } } } function arrayImplode($glue, $separator, $array) { if (! is_array ( $array )) return $array; $styleString = array (); foreach ( $array as $key => $val ) { if (is_array ( $val )) $val = implode ( '','', $val ); $styleString [] = "{$key}{$glue}{$val}"; } return implode ( $separator, $styleString ); } function getSelector($selectorName) { return $this->arrayImplode ( ":", ";", $this->css [$selectorName] ); } }

He estado usando CKEditor wysiwyg editor para un sitio web donde los usuarios pueden usar el editor HTML para agregar algunos comentarios. Terminé teniendo un código HTML anidado extremadamente redundante en mi base de datos que está ralentizando la visualización / edición de estos comentarios.

Tengo comentarios que se parecen a esto (este es un ejemplo muy pequeño. Tengo comentarios con más de 100 etiquetas anidadas):

<p> <strong> <span style="font-size: 14px"> <span style="color: #006400"> <span style="font-size: 14px"> <span style="font-size: 16px"> <span style="color: #006400"> <span style="font-size: 14px"> <span style="font-size: 16px"> <span style="color: #006400">This is a </span> </span> </span> </span> </span> </span> </span> <span style="color: #006400"> <span style="font-size: 16px"> <span style="color: #b22222">Test</span> </span> </span> </span> </span> </strong> </p>

Mis preguntas son:

  • ¿Hay alguna biblioteca / código / software que pueda realizar una limpieza inteligente (es decir, compatible con el formato) del código HTML, eliminando todas las etiquetas redundantes que no tienen ningún efecto en el formateo (porque están anuladas por las etiquetas internas)? He probado muchas soluciones en línea existentes (como HTML Tidy ). Ninguno de ellos hace lo que yo quiero.

  • Si no, tendré que escribir algún código para analizar y limpiar HTML. Estoy planeando usar PHP HTML DOM simple para recorrer el árbol HTML y encontrar todas las etiquetas que no tienen ningún efecto. ¿Sugiere algún otro analizador de HTML que sea más adecuado para mi propósito?

Gracias

.

Actualizar:

He escrito un código para analizar el código HTML que tengo. Todas las etiquetas HTML que tengo son:

  • <span> con estilos para font-size de font-size y / o color
  • <font> con atributos de color y / o size
  • <a> para enlaces (con href )
  • <strong>
  • <p> (etiqueta única para envolver todo el comentario)
  • <u>

Puedo escribir fácilmente algún código para convertir el código HTML en bbcode (por ejemplo, [b] , [color=blue] , [size=3] , etc.). Entonces, por encima de HTML, me convertiré en algo así como:

[b][size=14][color=#006400][size=14][size=16][color=#006400] [size=14][size=16][color=#006400]This is a [/color][/size] [/size][/color][/size][/size][color=#006400][size=16] [color=#b22222]Test[/color][/size][/color][/color][/size][/b]

La pregunta ahora es: ¿hay una manera fácil (algoritmo / biblioteca / etc) para limpiar el código bb (¿tan desordenado como el HTML original) que se generará?

gracias de nuevo


Aquí hay una solución que usa el navegador para obtener las propiedades del elemento anidado. No es necesario poner en cascada las propiedades, ya que los estilos calculados de css están listos para leerse en el navegador.

Aquí hay un ejemplo: jsfiddle.net/mmeah/fUpe8/3

var fixedCode = readNestProp($("#redo")); $("#simp").html( fixedCode ); function readNestProp(el){ var output = ""; $(el).children().each( function(){ if($(this).children().length==0){ var _that=this; var _cssAttributeNames = ["font-size","color"]; var _tag = $(_that).prop("nodeName").toLowerCase(); var _text = $(_that).text(); var _style = ""; $.each(_cssAttributeNames, function(_index,_value){ var css_value = $(_that).css(_value); if(typeof css_value!= "undefined"){ _style += _value + ":"; _style += css_value + ";"; } }); output += "<"+_tag+" style=''"+_style+"''>"+_text+"</"+_tag+">"; }else if( $(this).prop("nodeName").toLowerCase() != $(this).find(">:first-child").prop("nodeName").toLowerCase() ){ var _tag = $(this).prop("nodeName").toLowerCase(); output += "<"+_tag+">" + readNestProp(this) + "</"+_tag+">"; }else{ output += readNestProp(this); }; }); return output; }

Una mejor solución para escribir en todos los atributos de css posibles, como:
var _cssAttributeNames = ["font-size", "color"];
Es utilizar una solución como la mencionada aquí: ¿Puede jQuery obtener todos los estilos CSS asociados con un elemento?


Deberías mirar HTMLPurifier , es una gran herramienta para analizar HTML y eliminar contenido innecesario e inseguro. Mire en la eliminación de configuraciones de espacios vacíos y esas cosas. Puede ser un poco difícil de configurar, lo admito, pero eso es solo porque es muy versátil.

También es bastante pesado, por lo que querrá guardar la salida de la base de datos (a diferencia de leer el crudo de la base de datos y luego analizarlo con purificador todo el tiempo).


En lugar de desperdiciar su precioso tiempo de servidor analizando el código HTML incorrecto, le sugiero que corrija la raíz del problema.

Una solución simple sería limitar los caracteres que cada comentarista podría hacer para incluir todo el recuento de caracteres html en lugar de solo el conteo de texto (al menos eso detendría etiquetas anidadas infinitamente grandes).

Podrías mejorar eso al permitir al usuario cambiar entre la vista HTML y la vista de texto. Estoy seguro de que la mayoría de las personas verían una gran cantidad de basura en la vista HTML y simplemente presionarán CTRL + A y DEL.

Creo que sería mejor si tuviera sus propios caracteres de formato que analizaría y reemplazaría con el formato, es decir, como "desbordamiento de pila" tiene **bold text** , visible para el afiche. O simplemente haría BB-code, visible para el póster.


Es posible que no aborde exactamente su problema exacto, pero lo que habría hecho en su lugar es simplemente eliminar completamente todas las etiquetas HTML, retener solo texto doloroso y saltos de línea.

Una vez hecho esto, cambie a marcar nuestro código bb para formatear mejor sus comentarios. Un WYSIWYG rara vez es útil.

La razón es que usted dijo que todo lo que tenía en los comentarios eran datos de presentación, lo que francamente no es tan importante.


No tengo tiempo para terminar esto ... tal vez alguien más pueda ayudar. Este javascript también elimina etiquetas duplicadas exactas y etiquetas no permitidas ...

Hay algunos problemas / cosas por hacer,
1) las etiquetas regeneradas deben estar cerradas
2) solo eliminará una etiqueta si el nombre de etiqueta y los atributos son idénticos a otro dentro de los nodos hijos, por lo que no es lo suficientemente "inteligente" para eliminar todas las etiquetas innecesarias.
3) buscará a través de las variables de CSS permitidas y extraerá TODOS esos valores de un elemento, y luego lo escribirá en el HTML de salida, por ejemplo:

var allowed_css = ["color","font-size"]; <span style="font-size: 12px"><span style="color: #123123">

Será traducido a:

<span style="color:#000000;font-size:12px;"> <!-- inherited colour from parent --> <span style="color:#123123;font-size:12px;"> <!-- inherited font-size from parent -->

Código:

<html> <head> <script type="text/javascript"> var allowed_css = ["font-size", "color"]; var allowed_tags = ["p","strong","span","br","b"]; function initialise() { var comment = document.getElementById("comment"); var commentHTML = document.getElementById("commentHTML"); var output = document.getElementById("output"); var outputHTML = document.getElementById("outputHTML"); print(commentHTML, comment.innerHTML, false); var out = getNodes(comment); print(output, out, true); print(outputHTML, out, false); } function print(out, stringCode, allowHTML) { out.innerHTML = allowHTML? stringCode : getHTMLCode(stringCode); } function getHTMLCode(stringCode) { return "<code>"+((stringCode).replace(/</g,"&lt;")).replace(/>/g,"&gt;")+"</code>"; } function getNodes(elem) { var output = ""; var nodesArr = new Array(elem.childNodes.length); for (var i=0; i<nodesArr.length; i++) { nodesArr[i] = new Array(); nodesArr[i].push(elem.childNodes[i]); getChildNodes(elem.childNodes[i], nodesArr[i]); nodesArr[i] = removeDuplicates(nodesArr[i]); output += nodesArr[i].join(""); } return output; } function removeDuplicates(arrayName) { var newArray = new Array(); label: for (var i=0; i<arrayName.length; i++) { for (var j=0; j<newArray.length; j++) { if(newArray[j]==arrayName[i]) continue label; } newArray[newArray.length] = arrayName[i]; } return newArray; } function getChildNodes(elemParent, nodesArr) { var children = elemParent.childNodes; for (var i=0; i<children.length; i++) { nodesArr.push(children[i]); if (children[i].hasChildNodes()) getChildNodes(children[i], nodesArr); } return cleanHTML(nodesArr); } function cleanHTML(arr) { for (var i=0; i<arr.length; i++) { var elem = arr[i]; if (elem.nodeType == 1) { if (tagNotAllowed(elem.nodeName)) { arr.splice(i,1); i--; continue; } elem = "<"+elem.nodeName+ getAttributes(elem) +">"; } else if (elem.nodeType == 3) { elem = elem.nodeValue; } arr[i] = elem; } return arr; } function tagNotAllowed(tagName) { var allowed = " "+allowed_tags.join(" ").toUpperCase()+" "; if (allowed.search(" "+tagName.toUpperCase()+" ") == -1) return true; else return false; } function getAttributes(elem) { var attributes = ""; for (var i=0; i<elem.attributes.length; i++) { var attrib = elem.attributes[i]; if (attrib.specified == true) { if (attrib.name == "style") { attributes += " style=/""+getCSS(elem)+"/""; } else { attributes += " "+attrib.name+"=/""+attrib.value+"/""; } } } return attributes } function getCSS(elem) { var style=""; if (elem.currentStyle) { for (var i=0; i<allowed_css.length; i++) { var styleProp = allowed_css[i]; style += styleProp+":"+elem.currentStyle[styleProp]+";"; } } else if (window.getComputedStyle) { for (var i=0; i<allowed_css.length; i++) { var styleProp = allowed_css[i]; style += styleProp+":"+document.defaultView.getComputedStyle(elem,null).getPropertyValue(styleProp)+";"; } } return style; } </script> </head> <body onload="initialise()"> <div style="float: left; width: 300px;"> <h2>Input</h2> <div id="comment"> <p> <strong> <span style="font-size: 14px"> <span style="color: #006400"> <span style="font-size: 14px"> <span style="font-size: 16px"> <span style="color: #006400"> <span style="font-size: 14px"> <span style="font-size: 16px"> <span style="color: #006400">This is a </span> </span> </span> </span> </span> </span> </span> <span style="color: #006400"> <span style="font-size: 16px"> <span style="color: #b22222"><b>Test</b></span> </span> </span> </span> </span> </strong> </p> <p>Second paragraph. <span style="color: #006400">This is a span</span></p> </div> <h3>HTML code:</h3> <div id="commentHTML"> </div> </div> <div style="float: left; width: 300px;"> <h2>Output</h2> <div id="output"> </div> <h3>HTML code:</h3> <div id="outputHTML"> </div> </div> <div style="float: left; width: 300px;"> <h2>Tasks</h2> <big> <ul> <li>Close Tags</li> <li>Ignore inherited CSS style in method getCSS(elem)</li> <li>Test with different input HTML</li> </ul> </big> </div> </body> </html>


Recuerdo que Adobe (Macromedia) Dreamweaver, al menos las versiones antiguas tenían una opción, "Limpiar HTML", y también una "Limpiar palabra html" para eliminar etiquetas redundantes, etc. de cualquier página web.


Sé que estás buscando un limpiador HTML DOM, pero quizás js puede ayudar?

function getSpans(){ var spans=document.getElementsByTagName(''span'') for (var i=0;i<spans.length;i++){ spans[i].removeNode(true); if(i == spans.length) { //add the styling you want here } } }


Si quieres usar jQuery, prueba esto:

<p> <strong> <span style="font-size: 14px"> <span style="color: #006400"> <span style="font-size: 14px"> <span style="font-size: 16px"> <span style="color: #006400"> <span style="font-size: 14px"> <span style="font-size: 16px"> <span style="color: #006400">This is a </span> </span> </span> </span> </span> </span> </span> <span style="color: #006400"> <span style="font-size: 16px"> <span style="color: #b22222">Test</span> </span> </span> </span> </span> </strong> </p> <br><br> <div id="out"></div> <!-- Just to print it out --> $("span").each(function(i){ var ntext = $(this).text(); ntext = $.trim(ntext.replace(/(/r/n|/n|/r)/gm," ")); if(i==0){ $("#out").text(ntext); } });

Obtienes esto como resultado:

<div id="out">This is a Test</div>

Luego puede formatearlo de la forma que desee. Espero que te ayude a pensar un poco diferente al respecto ...


Trate de no analizar el HTML con DOM, pero tal vez con SAX (http://www.brainbell.com/tutorials/php/Parsing_XML_With_SAX.htm)

SAX analiza un documento desde el principio y envía eventos como ''inicio del elemento'' y ''fin del'' elemento ''para llamar a las funciones de devolución de llamada que usted defina

Luego puedes construir un tipo de pila para todos los eventos. Si tienes texto, puedes guardar el efecto de tu pila en ese texto.

Después de eso, procesa la pila para crear un nuevo HTML con el efecto que desee.


Cleanup HTML colapsa las etiquetas que parece ser lo que está pidiendo. Sin embargo, crea un documento HTML validado con CSS movido a estilos en línea. Muchos otros formateadores HTML no harán esto porque cambia la estructura del documento HTML.