una tablas tabla que obtener ejemplos datos con agregar javascript xml xslt pretty-print

tablas - Bonita impresión XML con javascript



tablas en javascript ejemplos (18)

Tengo una cadena que representa un XML sin sangría que me gustaría imprimir bastante. Por ejemplo:

<root><node/></root>

debe convertirse:

<root> <node/> </root>

El resaltado de sintaxis no es un requisito. Para abordar el problema, primero transformo el XML para agregar retornos de carro y espacios en blanco y luego uso una etiqueta pre para generar el XML. Para agregar nuevas líneas y espacios en blanco escribí la siguiente función:

function formatXml(xml) { var formatted = ''''; var reg = /(>)(<)(//*)/g; xml = xml.replace(reg, ''$1/r/n$2$3''); var pad = 0; jQuery.each(xml.split(''/r/n''), function(index, node) { var indent = 0; if (node.match( /.+<///w[^>]*>$/ )) { indent = 0; } else if (node.match( /^<///w/ )) { if (pad != 0) { pad -= 1; } } else if (node.match( /^</w[^>]*[^//]>.*$/ )) { indent = 1; } else { indent = 0; } var padding = ''''; for (var i = 0; i < pad; i++) { padding += '' ''; } formatted += padding + node + ''/r/n''; pad += indent; }); return formatted; }

Luego llamo a la función de esta manera:

jQuery(''pre.formatted-xml'').text(formatXml(''<root><node1/></root>''));

Esto funciona perfectamente bien para mí, pero mientras escribía la función anterior, pensé que debía haber una mejor manera. Entonces mi pregunta es, ¿conoces alguna forma mejor dada una cadena XML para imprimirla bastante en una página html? Cualquier marco de JavaScript y / o complementos que puedan hacer el trabajo son bienvenidos. Mi único requisito es que esto se haga en el lado del cliente.



¿Qué tal crear un nodo stub (document.createElement (''div'') - o usar el equivalente de tu biblioteca), rellenarlo con la cadena xml (a través de innerHTML) y llamar a la función recursiva simple para el elemento raíz / o el elemento stub en caso de que no tiene una raíz La función se llamaría a sí misma para todos los nodos secundarios.

Luego puede resaltar la sintaxis en el camino, asegúrese de que el marcado esté bien formado (hecho automáticamente por el navegador al agregarlo a través de innerHTML) etc. No sería tanto código y probablemente lo suficientemente rápido.


Del texto de la pregunta me da la impresión de que se espera un resultado de cadena , a diferencia de un resultado con formato HTML.

Si esto es así, la forma más sencilla de lograr esto es procesar el documento XML con la transformación de identidad y con una instrucción <xsl:output indent="yes"/> :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> </xsl:stylesheet>

Al aplicar esta transformación en el documento XML proporcionado:

<root><node/></root>

la mayoría de los procesadores XSLT (.NET XslCompiledTransform, Saxon 6.5.4 y Saxon 9.0.0.2, AltovaXML) producen el resultado deseado:

<root> <node /> </root>


Encontré este hilo cuando tenía un requisito similar, pero simplifiqué el código de OP de la siguiente manera:

function formatXml(xml, tab) { // tab = optional indent value, default is tab (/t) var formatted = '''', indent= ''''; tab = tab || ''/t''; xml.split(/>/s*</).forEach(function(node) { if (node.match( /^///w/ )) indent = indent.substring(tab.length); // decrease indent by one ''tab'' formatted += indent + ''<'' + node + ''>/r/n''; if (node.match( /^<?/w[^>]*[^//]$/ )) indent += tab; // increase indent }); return formatted.substring(1, formatted.length-3); }

¡funciona para mi!


Esto se puede hacer usando herramientas nativas de JavaScript, sin librerías de terceros, extendiendo la respuesta de @Dimitre Novatchev:

var prettifyXml = function(sourceXml) { var xmlDoc = new DOMParser().parseFromString(sourceXml, ''application/xml''); var xsltDoc = new DOMParser().parseFromString([ // describes how we want to modify the XML - indent everything ''<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">'', '' <xsl:output omit-xml-declaration="yes" indent="yes"/>'', '' <xsl:template match="node()|@*">'', '' <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>'', '' </xsl:template>'', ''</xsl:stylesheet>'', ].join(''/n''), ''application/xml''); var xsltProcessor = new XSLTProcessor(); xsltProcessor.importStylesheet(xsltDoc); var resultDoc = xsltProcessor.transformToDocument(xmlDoc); var resultXml = new XMLSerializer().serializeToString(resultDoc); return resultXml; }; console.log(prettifyXml(''<root><node/></root>''));

Productos:

<root> <node/> </root>

JSFiddle


Ligera modificación de la función javascript de efnx clckclcks. Cambié el formato de espacios a tabulación, pero lo más importante es que permití que el texto permaneciera en una línea:

var formatXml = this.formatXml = function (xml) { var reg = /(>)/s*(<)(//*)/g; // updated Mar 30, 2015 var wsexp = / *(.*) +/n/g; var contexp = /(<.+>)(.+/n)/g; xml = xml.replace(reg, ''$1/n$2$3'').replace(wsexp, ''$1/n'').replace(contexp, ''$1/n$2''); var pad = 0; var formatted = ''''; var lines = xml.split(''/n''); var indent = 0; var lastType = ''other''; // 4 types of tags - single, closing, opening, other (text, doctype, comment) - 4*4 = 16 transitions var transitions = { ''single->single'': 0, ''single->closing'': -1, ''single->opening'': 0, ''single->other'': 0, ''closing->single'': 0, ''closing->closing'': -1, ''closing->opening'': 0, ''closing->other'': 0, ''opening->single'': 1, ''opening->closing'': 0, ''opening->opening'': 1, ''opening->other'': 1, ''other->single'': 0, ''other->closing'': -1, ''other->opening'': 0, ''other->other'': 0 }; for (var i = 0; i < lines.length; i++) { var ln = lines[i]; // Luca Viggiani 2017-07-03: handle optional <?xml ... ?> declaration if (ln.match(//s*</?xml/)) { formatted += ln + "/n"; continue; } // --- var single = Boolean(ln.match(/<.+//>/)); // is this line a single tag? ex. <br /> var closing = Boolean(ln.match(/<//.+>/)); // is this a closing tag? ex. </a> var opening = Boolean(ln.match(/<[^!].*>/)); // is this even a tag (that''s not <!something>) var type = single ? ''single'' : closing ? ''closing'' : opening ? ''opening'' : ''other''; var fromTo = lastType + ''->'' + type; lastType = type; var padding = ''''; indent += transitions[fromTo]; for (var j = 0; j < indent; j++) { padding += ''/t''; } if (fromTo == ''opening->closing'') formatted = formatted.substr(0, formatted.length - 1) + ln + ''/n''; // substr removes line break (/n) from prev loop else formatted += padding + ln + ''/n''; } return formatted; };


O si simplemente quieres otra función js para hacerlo, he modificado la de Darin (mucho):

var formatXml = this.formatXml = function (xml) { var reg = /(>)(<)(//*)/g; var wsexp = / *(.*) +/n/g; var contexp = /(<.+>)(.+/n)/g; xml = xml.replace(reg, ''$1/n$2$3'').replace(wsexp, ''$1/n'').replace(contexp, ''$1/n$2''); var pad = 0; var formatted = ''''; var lines = xml.split(''/n''); var indent = 0; var lastType = ''other''; // 4 types of tags - single, closing, opening, other (text, doctype, comment) - 4*4 = 16 transitions var transitions = { ''single->single'' : 0, ''single->closing'' : -1, ''single->opening'' : 0, ''single->other'' : 0, ''closing->single'' : 0, ''closing->closing'' : -1, ''closing->opening'' : 0, ''closing->other'' : 0, ''opening->single'' : 1, ''opening->closing'' : 0, ''opening->opening'' : 1, ''opening->other'' : 1, ''other->single'' : 0, ''other->closing'' : -1, ''other->opening'' : 0, ''other->other'' : 0 }; for (var i=0; i < lines.length; i++) { var ln = lines[i]; var single = Boolean(ln.match(/<.+//>/)); // is this line a single tag? ex. <br /> var closing = Boolean(ln.match(/<//.+>/)); // is this a closing tag? ex. </a> var opening = Boolean(ln.match(/<[^!].*>/)); // is this even a tag (that''s not <!something>) var type = single ? ''single'' : closing ? ''closing'' : opening ? ''opening'' : ''other''; var fromTo = lastType + ''->'' + type; lastType = type; var padding = ''''; indent += transitions[fromTo]; for (var j = 0; j < indent; j++) { padding += '' ''; } formatted += padding + ln + ''/n''; } return formatted; };


Personalmente, uso google-code-prettify con esta función:

prettyPrintOne(''<root><node1><root>'', ''xml'')



Todas las funciones de javascript dadas aquí no funcionarán para un documento xml que tenga espacios en blanco no especificados entre la etiqueta de finalización ''>'' y la etiqueta de inicio ''<''. Para solucionarlos, solo necesita reemplazar la primera línea en las funciones

var reg = /(>)(<)(//*)/g;

por

var reg = /(>)/s*(<)(//*)/g;


Use el método anterior para imprimir bonito y luego agréguelo en cualquier div utilizando el método jquery text () . por ejemplo id de div es xmldiv luego use:

$("#xmldiv").text(formatXml(youXmlString));


aquí hay otra función para formatear xml

function formatXml(xml){ var out = ""; var tab = " "; var indent = 0; var inClosingTag=false; var dent=function(no){ out += "/n"; for(var i=0; i < no; i++) out+=tab; } for (var i=0; i < xml.length; i++) { var c = xml.charAt(i); if(c==''<''){ // handle </ if(xml.charAt(i+1) == ''/''){ inClosingTag = true; dent(--indent); } out+=c; }else if(c==''>''){ out+=c; // handle /> if(xml.charAt(i-1) == ''/''){ out+="/n"; //dent(--indent) }else{ if(!inClosingTag) dent(++indent); else{ out+="/n"; inClosingTag=false; } } }else{ out+=c; } } return out; }


considere usar el plugin vkBeautify

http://www.eslinstructor.net/vkbeautify/

está escrito en javascript simple, muy pequeño: menos de 1.5K si está minificado, muy rápido: menos de 5 mseg. para procesar texto XML 50K.


XMLSpectrum formats XML, admite la sangría de atributos y también resalta la sintaxis para XML y cualquier expresión XPath incrustada:

XMLSpectrum es un proyecto de código abierto, codificado en XSLT 2.0, por lo que puede ejecutar este servidor con un procesador como Saxon-HE (recomendado) o el lado del cliente utilizando Saxon-CE.

XMLSpectrum aún no está optimizado para ejecutarse en el navegador; de ahí la recomendación de ejecutar este servidor.



Or just print out the special HTML characters? Ex: <xmlstuff>&#10; &#09;<node />&#10;</xmlstuff> &#09; Horizontal tab &#10; Line feed


var formatXml = this.formatXml = function (xml) { var reg = /(>)(<)(//*)/g; var wsexp = / *(.*) +/n/g; var contexp = /(<.+>)(.+/n)/g; xml = xml.replace(reg, ''$1/n$2$3'').replace(wsexp, ''$1/n'').replace(contexp, ''$1/n$2''); var pad = 0; var formatted = ''''; var lines = xml.split(''/n''); var indent = 0; var lastType = ''other'';


var reg = /(>)/s*(<)(//*)/g; xml = xml.replace(//r|/n/g, ''''); //deleting already existing whitespaces xml = xml.replace(reg, ''$1/r/n$2$3'');