.net - tag - Problema con las etiquetas de cierre automático XSLT
qué es una etiqueta o tag en html (11)
Acabo de experimentar el mismo problema con PHP 5''s XSL, con output / @ method = html. Parece que la asignación de un atributo de valor vacío hará que los elementos salgan como etiquetas inválidas que no se cierran por sí mismas y que no están cerradas:
<input type="text" name="foo" value="{my-empty-value}" />
resultados en:
<input type="text" name="foo" value="">
Una posible solución es agregar de forma condicional el atributo:
<xsl:if test="string-length(my-empty-value) > 0">
<xsl:attribute name="value">
<xsl:value-of select="my-empty-value" />
</xsl:attribute>
</xsl:if>
Resultando en:
<input type="text" name="foo" />
Estoy usando xslt para transformar un archivo xml a html. El motor .net xslt me sigue sirviendo etiquetas de cierre automático para etiquetas vacías.
Ejemplo:
<div class="test"></div>
se convierte
<div class="test" />
El primero es html válido, mientras que el último es html ilegal y se procesa mal. Mi pregunta es: ¿Cómo le digo al motor xslt (XslCompiledTransform) que no use etiquetas de cierre automático?
Si no es posible, ¿cómo puedo decirle a mi navegador (IE6 + en este caso) que interprete correctamente las etiquetas de cierre automático?
Cambie su método xsl:output
para que sea html
(en lugar de xml
).
O agréguelo si aún no tiene el elemento
<xsl:output method="html"/>
Esto está relacionado con la clase XslCompiledTransform
aquí hay una solución:
Hay algunas cosas que debes tener cuidado:
- En tu xsl utiliza <xsl: output method = ''html''>
- establezca OutputSettings en su salida XmlWriter
- en el HTML dentro de su xsl, no configure los atributos en la etiqueta html como este <html xmlns = "http://www.w3.org/1999/xhtml"> sino que use <html>.
Esta es una pieza de código de trabajo:
string xmlStr = "<?xml version=''1.0'' encoding=''UTF-8''?><Data></Data>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlStr);
string xslContents = @"
<xsl:stylesheet version=''1.0'' xmlns:xsl=''http://www.w3.org/1999/XSL/Transform''
xmlns:msxsl=''urn:schemas-microsoft-com:xslt'' exclude-result-prefixes=''msxsl''>
<xsl:output method=''html'' version=''4.0'' omit-xml-declaration=''yes'' indent=''yes''/>
<xsl:template match=''Data''>
<html>
<body>
<div></div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>";
XslCompiledTransform xsl = new XslCompiledTransform();
xsl.Load(XmlReader.Create(new StringReader(xslContents)));
StringWriter result = new StringWriter();
using (XmlWriter writer = XmlWriter.Create(result, xsl.OutputSettings))
{
xsl.Transform(doc, null, writer);
}
System.Diagnostics.Debug.Write( result.ToString());
La manera más fácil que encontré fue crear una nueva clase XmlTextWriter para anular el método WriteEndElement, forzando la etiqueta que no cierra y pasar el proceso de serialización como parámetro.
public class MyXmlTextWriter : XmlTextWriter
{
public MyXmlTextWriter(Stream stream) : base(stream, Encoding.UTF8)
{ }
public MyXmlTextWriter(TextWriter stream) : base(stream)
{ }
public override void WriteEndElement()
{
base.WriteFullEndElement();
}
}
No puede decirle a su navegador que maneje HTML no válido como HTML; tiene suerte de que comprenda HTML mal formado. :)
Definitivamente haz esto en tu hoja de estilo:
<xsl:output method="html"/>
Pero, si su documento fuente tiene espacios de nombres, esto no servirá. Los procesadores XSLT parecen cambiar silenciosamente el método de salida a XML si los nodos de espacio de nombres están presentes en la salida.
Necesita reemplazar todas las instancias de <xsl:copy-of>
y <xsl:copy>
con creaciones de elementos con solo el nombre local, por ej.
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
Ver
- http://www.biglist.com/lists/xsl-list/archives/200708/msg00538.html
- http://www.stylusstudio.com/xsllist/200509/post90860.html
- http://www.richardhallgren.com/removing-namespace-from-outgoing-messages/
etc.
Para mí fue un problema en la etiqueta de script . Lo resolví llenándolo con un punto y coma ( ; )
<script type="text/javascript" src="somewhere.js">;</script>
Si está utilizando XmlWriter como su flujo de salida, use HTMLTextWriter en su lugar. XMLWriter volverá a formatear su salida de HTML a XML.
Solía poner un elemento <xsl:text>
dentro, como:
<script type="text/javascript" src="/scripts/jquery.js"><xsl:text> </xsl:text></script>
Una solución alternativa puede ser insertar un elemento de comentario para forzar la generación de un cierre no automático:
<script type="text/javascript" src="nowhere.js">
<xsl:comment></xsl:comment>
</script>
No es una solución bonita, pero funciona :-)
/ Sten
Uso lo siguiente cuando deseo evitar que un elemento se cierre automáticamente:
<xsl:value-of select="''''" />
Esto engaña al motor de renderizado para que crea que hay contenido dentro del elemento y, por lo tanto, impide el cierre automático.
Es una solución bastante desagradable, por lo que recomiendo que la incluyas en una plantilla descriptiva y que en su lugar la invoques cada vez:
<xsl:template name="PreventSelfClosure">
<xsl:value-of select="''''" />
</xsl:template>
<div class="test">
<xsl:call-template name="PreventSelfClosure"/>
</div>
Esto representará lo siguiente:
<div class="test"></div>
http://curtistimson.co.uk/post/xslt/how-to-prevent-self-closing-elements-in-xslt/