HTML, XML y XSL: Guia de convivencia
A pedido popular…
He aquí un pequeño resumen de como hice para meter HTML dentro de XML y que saliese bien. Notese que dije 'pequeño resumen', voy a explicar como se hace para meter HTML en XML y que en la transformación XSL lo trate como HTML y no XML. Usaré como ejemplo el código que escribí para Caleio.
Como saben HTML y XML son derivados de SGML, ambos usan etiquetas y funcionan de manera similar, y ahí esta el problema. Al meter HTML en el XML el transformador XSL no sabe que es HTML y lo trata como XML normal. El problema salió cuando quise meter enlaces (o cualquier otro elemento HTML como imágenes o saltos de linea) en las descripciones de elementos. Simplemente no los mostraba porque intepretaba que eran etiquetas XML.
La solución es muy simple, pero me costó mucho encontrarla porque todo el mundo tiene un método distinto. Este consiste en indicar en el archivo XML cuales etiquetas son especiales, en este caso de HTML. Por ejemplo:
<?xml version="1.0" standalone="yes"?>
<event>
<item>
<id>325</id>
<startDate>2005-08-16</startDate>
<endDate>2005-08-16</endDate>
<startTime>21:00:00</startTime>
<endTime>22:00:00</endTime>
<eventType>1</eventType>
<scheduled>0</scheduled>
<repetition>0</repetition>
<title>testing</title>
<description xmlns:html="http://www.w3.org/1999/xhtml">something with a <html:br />
<html:a href="http://www.google.com">link</html:a></description>
</item>
</event>
La etiqueta description
es la que lleva el HTML, el atributo xmlns
lo reconocerán de la etiqueta html
que se usa en XHTML. xmlns
(http://www.w3.org/TR/REC-xml-names/) sirve para definir Namespaces en XML, los namespaces son definiciones específicas de etiquetas, como en XML una etiqueta no tiene significado alguno con namespaces se puede definir mas correctamente. Que es justo lo que hace xmlns
en la etiqueta html
en XHTML:
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
XHTML es XML, pero con el atributo xmlns
le decimos al navegador que todo lo que hay dentro de la etiqueta html
debe ser tratado como tal. Esto no es estrictamente necesario porque los navegadores lo detectan automaticamente, pero el validador de HTML tira error si se omite.
Aquí es donde entramos en terreno desconocido, algunas de las páginas que leí decian que con tal de poner el xmlns
en la etiqueta que tuviese el HTML dentro ya bastaba, pero a mi se me hizo necesario poner :html
para indicarle a XSL exactamente cuales etiquetas eran HTML. También sugerian poner la definición xmlns:html
en la etiqueta raiz, lo cual es lógico porque al especificar con :html
cuales son debería reconocerlas, pero a mi no me funcionó. Así que hay que declarar xmlns:html
y luego todas las etiquetas van de la forma html:nombre_de_etiqueta
. Esto es un problema porque hay que usar expresiones regulares para meter el html:
en todas las etiquetas, y para colmo cuando se usa xmlhttprequest hay que sacarlas en el Javascript antes de mostrarlas porque las estás metiendo despues de la conversión XSL. Para ello escribí una función que parsea el XML y lo transforma en HTML:
function xml2html(xml)
{
var i=0;
var j=0;
var html= "";
var tagName = "";
for (i=0;i<xml.childNodes.length;i++)
{
/* If it's not a text node then we need to continue searching within it */
if (xml.childNodes[i].nodeType != 3)
{
/* Test for single tag elements */
if (xml.childNodes[i].childNodes.length!=0)
{
/* Converts html:b into <b></b> with the stuff inside */
tagName = xml.childNodes[i].nodeName.split(':')[1];
fullTag = tagName;
for(j=0;j<xml.childNodes[i].attributes.length;j++)
{
fullTag = fullTag + ' '+xml.childNodes[i].attributes[j].name+'='+xml.childNodes[i].attributes[j].value;
}
html = html + '<'+fullTag+'>' + xml2html(xml.childNodes[i]) + '</'+tagName+'>';
} else {
/* This is for single tag elements i.e.: <br /> and <img /> */
fullTag = xml.childNodes[i].nodeName.split(':')[1];
for(j=0;j<xml.childNodes[i].attributes.length;j++)
{
fullTag = fullTag + ' '+xml.childNodes[i].attributes[j].name+'='+xml.childNodes[i].attributes[j].value;
}
html = html + '<'+fullTag+' />';
}
} else {
/* If it is a text node, just get the data and append to previous html */
html = html + xml.childNodes[i].data;
}
}
return html;
}
Un último detalle: para usarlo en una conversión XSL hay que usar la etiqueta <xsl:copy-of select="event//description" />
y no <xsl:value-of select="event//description" />
. No me acuerdo que cosa mágica hace copy
que no hace value
pero sé que sino no funciona.
4 Responses to HTML, XML y XSL: Guia de convivencia
Leave a Reply Cancel reply
This site uses Akismet to reduce spam. Learn how your comment data is processed.
-
Articles
- October 2014
- May 2011
- April 2011
- January 2011
- December 2010
- November 2010
- September 2010
- August 2010
- July 2010
- February 2010
- December 2009
- August 2009
- June 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
- December 2005
- November 2005
- October 2005
- September 2005
- August 2005
- July 2005
- December 2004
- November 2004
- October 2004
- September 2004
- August 2004
- July 2004
- June 2004
- May 2004
- April 2004
- March 2004
- February 2004
- January 2004
- December 2003
- November 2003
- October 2003
- September 2003
- August 2003
- July 2003
-
Meta
¿Encerrar el HTML en una sección CDATA no era una opción?
Si, esa opcion me la olvide, pero tampoco me funciono, Es mas, fue lo primero que probe, porque asi se hace en el feed RSS. El problema viene por culpa de la transformacion XSL, asi que lo que funciona para el feed RSS no tiene porque funcionar en la transformacion.
:D ¡Ya era hora! Hace meses que lo prometiste :P
PD: ¿popular?
Curioso lo que decis. CDATA es parte de XML (está más alla de RSS). Mala suerte entonces.
Notece que igualmente toco bastante de oido. :)