- Se puede usar XSLT como un sistema de compilación del lado del cliente que se ejecuta en el navegador web para transformar datos XML en HTML y reducir la complejidad de los generadores de sitios estáticos
- Un sitio estático típico se compone de datos como
.json, .md y .txt, un sistema de compilación como Hugo, Next.js o Astro, y una salida HTML estática, pero los frameworks grandes pueden introducir una complejidad excesiva incluso para un blog sencillo en Markdown
- Si se intenta usar solo HTML y CSS, hay que copiar manualmente el encabezado y el pie de página en múltiples páginas; además, no existen los HTML imports y los Web Components requieren un motor de JavaScript
- Si se agrega
<?xml-stylesheet type="text/xsl" href="blog.xsl"?> a un documento XML y se escriben plantillas XSLT, el navegador puede generar la salida HTML en el momento de la visita
- Este enfoque puede desplegarse como archivos estáticos sin JavaScript, aunque no es una solución perfecta que reemplace todo, sino otra opción para sumar a la caja de herramientas del desarrollo web
La complejidad de compilar sitios estáticos
- El flujo típico de creación de un sitio web estático se divide en datos, sistema de compilación y salida HTML estática
- Los datos se guardan en archivos como
.json, .md y .txt
- Algunos ejemplos de sistemas de compilación son Hugo, Next.js y Astro
- El resultado final es HTML estático
- Aunque se quiera eliminar frameworks y usar solo HTML y CSS, cuando aumentan las páginas hay que seguir copiando el encabezado y el pie de página comunes
- Las alternativas que podrían venir a la mente tienen sus propias limitaciones
- No existen los HTML imports
- Los Web Components requieren JavaScript y, por lo tanto, un motor de JavaScript
La idea de usar el navegador como sistema de compilación
- El navegador web ya puede entender varios formatos como
text/html, text/markdown y application/xml
- Si se usa el navegador como sistema para generar HTML a partir de datos, se puede crear un flujo basado en estándares web sin herramientas de compilación separadas
- Mientras intentaba mostrar un feed RSS de una forma más agradable, el autor descubrió que XSLT puede usarse como hoja de estilo para documentos XML
- XML se parece a HTML, pero es una forma de representar datos que no se limita a datos web, como puede verse en la especificación XML
Cómo transformar de XML a HTML
- Un documento XML puede contener datos como entradas de blog
<?xml version="1.0"?>
<blog>
<post id="42" publishedAt="2025-06-26">
<title>Hello XSLT</title>
<tags>…</tags>
</post>
</blog>
- Se puede agregar una declaración que vincule una hoja de estilo XSL al documento XML
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="blog.xsl"?>
<blog>
<post id="42" publishedAt="2025-06-26">
<title>Hello XSLT</title>
<tags>…</tags>
</post>
</blog>
- Una plantilla XSLT toma la entrada XML y produce una estructura HTML
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
<html>
<head> … </head>
<body> … </body>
</html>
</xsl:template>
</xsl:stylesheet>
- XSLT puede verse como una forma de
(XML) => HTML y ofrece funciones de sistema de compilación como bucles, variables e imports
- También puede tomar datos del documento XML padre y mostrarlos de forma dinámica
<head>
<xsl:value-of select="title" /> | Blog
</head>
Ejecución y despliegue
- Se puede ejecutar la transformación XSLT al abrir el archivo XML en el navegador
open blog.xml -a Safari
- Todos los navegadores web admiten la transformación XSLT al visitar la página y muestran el HTML resultante
- Este enfoque funciona como un sistema de compilación del lado del cliente que se ejecuta en la computadora del usuario
- Facilita el despliegue de archivos estáticos y funciona sin JavaScript
Limitaciones y posicionamiento
- Los datos del blog deben guardarse en XML en lugar de JSON, pero XML se parece a HTML, es fácil de parsear, flexible y cuenta con soporte nativo en la web
- El enfoque con XSLT no es perfecto y no reemplaza todo
- Aprovecha estándares web, especificaciones y funciones del navegador de larga data para convertirse en otra herramienta útil para crear sitios web estáticos simples
1 comentarios
Opiniones de Hacker News
Trabajé en una empresa que usaba mucho XSLT para plantillas XML, y no era bueno; si hubiera sido posible, probablemente nos habríamos mudado a otra cosa.
Aunque hay estándares nuevos, XSLT 1.0 sigue dominando, y es limitado y extraño comparado con los estándares modernos.
Resolver problemas de rendimiento en plantillas XSLT es casi un infierno. Es un lenguaje de estilo funcional Turing completo, pero el rendimiento está muy abstraído; una plantilla que funcionaba bien en la mayoría de los documentos podía explotar con una sola tabla de 100 filas. Resultaba que la plantilla que procesaba la tabla era O(N^2) o peor, y que en cada fila el XPath podía volver a ser O(N) o peor, sin que hubiera una forma clara de optimizarlo. Según recuerdo, procesar un solo documento con XSLT tomaba más de 7 minutos.
JS tendrá otros problemas, pero no poder resolver problemas de complejidad algorítmica no es uno de ellos.
Ahora funciones como key (índice) pueden acelerar mucho el procesamiento, y buenas implementaciones de XSLT como Saxon también ayudan claramente en rendimiento.
Al convertir XML a otros formatos, XSLT resulta bastante cómodo porque permite estructurar la lógica.
En 2013 usaba mucho XSLT, y para entonces 1.0 ya estaba completamente muerto en todos lados. Saxon era gratis para XSLT 2 y era excelente.
Transformamos tanto documentos enormes como muchos documentos pequeños, y no tuvimos ningún problema de rendimiento.
Una vez que lo dominas, da una satisfacción parecida a resolver un sudoku, pero normalmente bastan herramientas mucho más pequeñas para lograr el objetivo, así que es difícil que se convierta en el enfoque estándar para builds o plantillas.
Además, XML tampoco es un formato que le guste a todo el mundo.
Si mal no recuerdo, también hacía optimizaciones bastante inteligentes.
Puede ser una conjetura bastante forzada, pero en los años 1990 y 2000 los navegadores eran muy distintos entre sí, así que se empezó a usar JS para lograr el mismo comportamiento, cuando en realidad lo que hacía falta eran buenos estilos CSS y un comportamiento consistente.
Con el tiempo, los navegadores empezaron a comportarse de forma similar, pero ya nos habíamos acostumbrado a frameworks que hacían que las páginas se vieran igual en todos los navegadores, y el paradigma cambió a renderizar datos JSON.
Con el nivel tecnológico actual, el servidor puede manejar perfectamente páginas web a la antigua generadas por él; tienen una huella más pequeña, son más rápidas y usan menos memoria.
Hace poco, al migrar un sistema legado, vi una arquitectura estilo años 2000 de “una página por cada solicitud HTTP”, y aunque todas las acciones como agregar/eliminar requerían recargar, era mucho más rápida que el sistema en React. Internet se volvió más rápido, la memoria de los celulares la desperdician los frameworks de JS, y el backend sigue siendo en su mayoría CRUD, paginación y transacciones.
En sitios simples como HN, la recarga completa de página encaja bien, y hay muchos casos donde un sitio web simple basta en lugar de un framework de JS.
Pero no es cierto que todo el mundo pueda volver a recargas completas de página. En algunas aplicaciones web reales, una recarga completa genera una experiencia de usuario horrible.
En general, los sitios web, documentos web y formularios web pueden funcionar con recargas completas, pero eso no encaja con aplicaciones web que tienen que mostrar y manipular cosas complejas.
En esa época, para ajustar el layout se dependía de la detección del agente de usuario y de todo tipo de quirks, y tampoco parece que JS tuviera acceso fácil a elementos relacionados con el layout.
CSS tampoco trajo consistencia de inmediato. Incluso después de tener funcionalidades, seguía siendo un desastre; era la época en que todos se maravillaban con CSS Zen Garden, pero el código real se hacía con tablas.
Tampoco sé si los frameworks influyeron mucho en la “apariencia consistente”. Para cuando dejamos atrás jQuery, CSS ya se encargaba del aspecto visual.
Esto bajo condiciones en las que se hacen varias consultas por página y se usan muchos joins complejos para construir una forma de respuesta específica para la vista. Traer los datos en la forma correcta antes de interpolarlos en cadenas HTML ayuda mucho al rendimiento en casos límite como tablas de 100 mil filas.
Por experiencia, cuanto más cerca estén el motor de plantillas HTML y la base de datos, mejor. Al final, incluso un DOM estructurado no es más que un flujo de bytes que hay que enviar al cliente.
Creo que se creó una industria sin sentido y autocomplaciente, preocupándose por enfoques sofisticados de AST/parser donde bastaban StringBuilder y consultas SQL inteligentes. El argumento contrario suele terminar en una actitud de vigilante de seguridad que asume que los desarrolladores no saben usar bien una función de escape de HTML.
Es una lástima que, por la pesadez del XML empresarial de los años 2000, la tecnología terminara pareciendo vieja y todos se fueran hacia el JSON más “limpio”.
XSLT y XPath son muy maduros y ya resolvieron muchos problemas que otros formatos todavía siguen sufriendo.
También tengo buenos recuerdos de cuando abusaba de los stream wrappers de PHP y de los include de XSLT.
Quizá sea un prejuicio viejo, pero todavía me da un poco de desconfianza dejar que el navegador lo procese localmente. Antes era un campo minado de compatibilidad.
Cosas del lado de XML, como los esquemas, estaban mucho mejor definidas, y siento que a JSON le tomó casi 10 años ponerse al día.
La última tecnología XML que manejé en serio fue EXI, que era una forma de transporte que convertía documentos XML en streams de datos binarios comprimidos. Porque convertir una estructura de datos a ASCII, comprimirla, mandarla por HTTP y luego revertir todo es algo un poco ridículo.
Hoy la familia de protobuf es más popular, pero si XML hubiera seguido presente, quizá habríamos terminado en un mundo de estándares compatibles que encajaban entre sí. En cambio, entre protobuf/gRPC y las API JSON hay una barrera sólida, aunque tal vez eso sea mejor.
XPath tampoco está mal. Es difícil recordar toda la sintaxis, pero con un poco de experimentación casi siempre llegas a donde quieres.
XSLT es una estupidez completamente demente y debería arder hasta desaparecer.
Como combinación para permitir modificaciones locales relativamente estables de los datos, XML + XPath está muy subestimado. Quizá por la reputación de XML como algo “anticuado”, no lo he visto mucho en otros juegos, pero para este uso es un sistema muy sólido.
https://rimworldwiki.com/wiki/Modding_Tutorials/PatchOperati...
Pero cuando creció la fiebre web, el W3C y MS crearon cosas como SOAP y WS-*, y también surgieron varios lenguajes de programación basados en XML, incluido XSLT.
No debería decirles esto a los de HN, pero XSLT originalmente era Scheme, solo que tenía que ser XML, en esa misma época de locura en la que JavaScript tenía que tomar prestado el nombre de Java.
Hoy en día uso XSLT para darle estilo a los feeds.
Por ejemplo, https://susam.net/feed.xml y https://susam.net/feed.xsl.
A los 19 años, uno de mis primeros proyectos como ingeniero de software profesional fue personalizar dos Google Search Appliance que la empresa había comprado.
La empresa pensaba que poder hacer búsqueda de texto completo en un enorme repositorio de documentos CIFS mejoraría el proceso de desarrollo de negocios, así que gastó cientos de miles de dólares en racks de servidores Dell con frente amarillo, corriendo CentOS y Python al estilo Google.
Alrededor de 2011, XHTML estaba de moda, y GSA convertía con XSLT a XHTML los resultados de búsqueda que el backend entregaba en XML.
Tomé la plantilla base y, con recursos y marcado robados de páginas renderizadas de una aplicación ColdFusion, StackOverflow y tutoriales de W3Schools, armé un monstruo parecido a un portal de intranet corporativo.
Después, varios contratistas del DoD me contactaron por LinkedIn para participar en proyectos de modernización documental al ver mi “experiencia en XML”, y aprendí rápido que tenía que sacar esa experiencia del CV.
Cuando suspiro mientras itero en JSX sobre un arreglo de interfaces TypeScript deserializadas desde una respuesta JSON, solo tengo que acordarme de mí haciendo lo mismo con XSLT.
Mucha gente se queja de que XML es verboso y de lejos parece complejo, pero me gusta que con XML puedas crear buenos formatos de archivo, validarlos con DTD y, si hace falta, formatearlos con XSLT para que sean legibles por humanos.
XML es como el C++ de los formatos de archivo basados en texto. Es maduro, trae las baterías incluidas, es potente y, si quieres, puedes usarlo desde cualquier lenguaje.
Así como se critica a los lenguajes viejos y maduros por sus rarezas, también se volvió moda criticar a XML. Si no encaja con tu caso de uso, no lo uses, pero tampoco hay que tratarlo como un monstruo.
Como ejemplo de lo lejos que llegaron XML y XSLT a principios de los 2000, una empresa donde trabajé antes fabricaba un ASIC que parseaba XML a velocidad de línea y procesaba XSLT de forma nativa en el chip.
Era porque esperaban que el futuro de Internet fuera todo XML/XSLT. Intel compró esa empresa, y la tecnología interna terminó entrando en aceleradores SSE.
Me sorprende la magia de que “XSLT funcione de forma nativa en el navegador”
La última vez que usé XSLT fue hace unos 20 años, pero en aquel entonces lo usé muchísimo durante varios años. En esa época, para hacerlo funcionar se necesitaba una enorme y tambaleante torre Java empresarial, lo que le restaba elegancia al propio XSLT
Pero si XSLT realmente funciona en el navegador, entonces el santo grial de las plantillas estáticas que se pueden alojar en cualquier lugar siempre estuvo justo delante de nuestras narices
Más bien, si se agregara soporte para v3, creo que sería más fácil ofrecer páginas web estáticas con soporte nativo de plantillas
El CMS emitía archivos XML con HTML incrustado, y se cacheaba muy bien. La personalización y el renderizado de HTML/JS se manejaban del lado del servidor junto con un proxy de caché
La transformación XSL se ejecutaba detrás de la caché y era lo bastante rápida como para seguirle el ritmo a mucho tráfico. El propósito de XML aquí era meter el HTML ya preparado como blobs y dejar como etiquetas XML solo las partes que necesitaban personalización
La transformación final era bastante rápida, y la clave era no guardar la salida del transformador XSL en un búfer completo en memoria, sino enviarla directamente al stream de salida de la respuesta. Para respuestas grandes sigue siendo una buena técnica incluso hoy, pero muchos frameworks la pasan por alto porque eligen el buffering en memoria como valor predeterminado
Hoy, por supuesto, con wasm se puede ejecutar en el navegador lo que uno quiera. Pero en aquel entonces JavaScript era un desastre, y lo mejor que los diseñadores podían hacer era entregarte archivos de Photoshop. Había que cortarlos en frames y tablas, y en la época en que recién salían Google Maps y Gmail estábamos construyendo una UI de CMS bastante cargada de JavaScript, soportando tanto Netscape como Internet Explorer
Firefox tiene un bug especialmente molesto: cuando necesitas
disable-output-escapingpara renderizar HTML dentro del documento como DOM real, no funciona correctamente y se renderiza como texto HTML crudoEn un proyecto distópico de hace mucho tiempo, en una galaxia muy lejana, alguien que era pesimista sobre la capacidad del equipo para coordinar el desarrollo en Java en paralelo con workbooks que cambiaban rápidamente propuso una solución
La estructura era que Visual Basic convertía los workbooks escritos en Excel a XML, y archivos XSLT generaban automáticamente las clases Java que procesarían las acciones de Struts definidas en ese XML
https://raganwald.com/2008/02/21/mouse-trap.html
Discusiones en HN: https://news.ycombinator.com/item?id=120379 · https://news.ycombinator.com/item?id=947952