2008-12-03 10 views
10

Estoy usando xslt para transformar xml en un archivo aspx. En xslt, tengo una etiqueta de script para incluir un archivo jquery.js. Para que funcione con IE, la etiqueta del script debe tener una etiqueta de cierre explícita. Por alguna razón, esto no funciona con xslt a continuación.Etiqueta de fin de script explícita siempre convertida en autocierre

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
    xmlns:asp="remove">  
    <xsl:output method="html"/> 
    <xsl:template match="/"> 
     <html xmlns="http://www.w3.org/1999/xhtml"> 
      <head> 
       <title>TEST</title> 
       <script type="text/javascript" src="jquery-1.2.6.js"></script> 

Pero si cambio la etiqueta del script como se muestra a continuación, funciona.

 <script type="text/javascript" src="jquery-1.2.6.js"> 
      // <![CDATA[ // ]]> 
     </script> 

pensé que el <xsl:output method="html" /> que hacer el truco, pero no parece funcionar?

/Jonas

Respuesta

0

Y esto está en contra de motor XSLT de MS por supuesto? Que extraño. No puedo decir que he encontrado esto en .NET 1.1 o 2.0 y tengo una serie de transformaciones que hacen exactamente lo mismo, por lo que le sugiero que vaya con la solución simple.

4

Esto es un problema bastante común al generar HTML de XSLT. Sospecho que la raíz del problema es que el XSLT en sí mismo es un documento XML. Aunque empiece con su programa XSLT como XML serializado, para cuando lo reciba el procesador XSLT, ya se ha deserializado a una representación de "infoset". En un nivel XML, una etiqueta vacía y una autocompletada son equivalentes; el elemento simplemente no tiene hijos. Esto significa que su procesador XSLT probablemente nunca verá una versión del programa donde el elemento del script tenga una etiqueta de apertura y cierre.

Normalmente lo soluciono utilizando un espacio adecuado sin escapes. En cualquier caso, debes poner algo dentro de la etiqueta del script.

Por cierto, esto no se trata de hacer feliz a IE. Si observa el HTML spec, encontrará que se requiere la etiqueta de cierre. Estoy seguro de que a algunas personas les parecerá irónico que IE lo implemente correctamente. :-)

7

Si va a crear XmlWriter a sí mismo que necesita para aprobar los OutputSettings de transformar a la XmlWriter, por ejemplo:

XmlDocument doc = new XmlDocument(); 
doc.LoadXml("<book><author>Trudi Canavan</author><title>Voice of the Gods</title></book>"); 

XslCompiledTransform transform = new XslCompiledTransform(); 
transform.Load("XSLTFile1.xslt"); 

StringBuilder output = new StringBuilder(); 

// Here we pass the output setting to the writer, otherwise the transform 
// may be set to Html, but the XmlWriter will be outputting Xml 
XmlWriter writer = XmlWriter.Create(output, transform.OutputSettings); 

transform.Transform(doc, writer); 

Console.WriteLine(output.ToString()); 
Console.ReadKey(); 
0

que utilizan un comentario antes de etiqueta final script para pasar por este problema.

1

Esto es por diseño y la única solución que conozco es el uso de una costumbre XmlTextWriter:

public class HtmlTextWriter : XmlTextWriter 
{ 
    private readonly string[] fullEndElements = 
     new string[] { "script", "title" }; 

    private string lastStartElement = null; 


    public HtmlTextWriter(TextWriter textWriter) 
     : base(textWriter) 
    { 
    } 

    public HtmlTextWriter(string filename, Encoding encoding) 
     : base(filename, encoding) 
    { 
    } 

    public HtmlTextWriter(Stream w, Encoding encoding) 
     : base(stream, encoding) 
    { 
    } 

    public override void WriteStartElement(string prefix, string localName, string ns) 
    { 
     lastStartElement = localName; 
     base.WriteStartElement(prefix, localName, ns); 
    } 

    public override void WriteEndElement() 
    { 
     if (Array.IndexOf(fullEndElements, lastStartElement) > -1) 
     { 
      base.WriteFullEndElement(); 
     } 
     else 
     { 
      base.WriteEndElement(); 
     } 
    } 
} 
0

Para aquellos de ustedes usando Xalan 2.7.0 (en Java), que tenía el mismo problema. Adopté el archivo org/apache/xml/serializer/ToStream.java en el código fuente original para evitar este problema. Si especifica como outputProperty:

private static Properties XHTML() { 
    Properties p = new Properties(); 
    p.setProperty(OutputKeys.METHOD, "xhtml"); 
    p.setProperty(OutputKeys.DOCTYPE_PUBLIC, 
    "-//W3C//DTD XHTML 1.0 Strict//EN"); 
    p.setProperty(OutputKeys.DOCTYPE_SYSTEM, 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); 
    p.setProperty(OutputKeys.ENCODING, "UTF-8"); 
    p.setProperty("{http://xml.apache.org/xalan}indent-amount", "4"); 
    p.setProperty(OutputKeys.INDENT, "yes"); 
    p.setProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); 
    p.setProperty("{http://example.com}selfclosing","no"); 
    return p; 
} 

Nota la última línea de selfclosing. Esta es una propiedad a la que se responde en esta versión renovada de ToStream.java y evitará las etiquetas <div /> y <script /> y las etiquetas de salida <div></div> y <script></script> en su lugar. También incluye excepciones a esto, es decir, las que se especifican en el estándar HTML como autorrellenadas (es decir, "área", "base", "basefont", "br", "col", "fotograma", "hora"). "," img "," entrada "," enlace "," meta "," param "). Me funcionó al menos, y ahora las páginas web también están bien en IE.

El nuevo archivo ToStream.java se puede encontrar en http://bvandelft.ruhosting.nl/ToStream.java y una versión precompilada del serializer.jar (trabajando con 2.7) también está disponible en la misma URL, pero serializer.jar (en el que se incluye la versión compilada de ToStream) no pudo publicar más de 1 URL :-p

+0

Soy consciente de que puede agregar un comentario en la secuencia de comandos para piratear esto también, sin embargo, esto no resolverá el problema de tener, p. Ej. DIVs vacíos, de ahí esta solución a mayor escala. –

1

La respuesta de Bart van Delfts me indicó la dirección correcta con este, ¡así que aplaude!

que estaba teniendo este problema, así utilizando [javax.xml.transform.Transformer] Siempre que trataba de analizar un fragmento de código HTML formateado, en mi caso: -

<textarea></textarea>

la final salida desde el nodo estaba siendo llevado en mi JSP como: -

<textarea/> 

que fue, obviamente, arruinando cualquier código siguiente, debido a que es visto como más de los contenidos del elemento de área de texto.

configuración t.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "html"); parece haber proporcionado el comportamiento de autocierre que esperaba. Esta propiedad tiene como valor predeterminado "xml" de mi propia prueba, por lo que obviamente una etiqueta xml sin nodos debajo es perfectamente feliz como cierre automático.

Espero que esto ayude de todos modos.

1

Considere este ejemplo,

<Discount> 
     <!--<xsl:if test="Discount>0">--> 
      <xsl:value-of select="Discount"/> 
     <!--</xsl:if>--> 
</Discount> 

si estoy trabajando con descuento para un producto. y lo estoy verificando antes de su uso. devolverá la salida,

<Discount>value of the discount</Discount> 

Pero si yo no-comento el ejemplo anterior de esa manera,

<Discount> 
     <xsl:if test="Discount>0"> 
      <xsl:value-of select="Discount"/> 
     </xsl:if> 
</Discount> 

que va a devolver la O/P después de XSLT como (si descuento es> 0),

<Discount/> 
3

que esta respuesta es el sitio del foro de MSDN:

<xsl:value-of select="' '"/> 

Si agrega el código xslt anterior antes de que termine en el archivo xsl, obliga al elemento a tener algún contenido (espacio en este caso) en lugar del propio cierre automático. Lo intenté y funcionó.

Esto es lo que se creó:

<script...> </script> 

en lugar de

<script ... />. 
0

Como se ha mencionado, hay trucos con poner un contenido invisible en el elemento pero en XSLT siempre se puede hacer que la salida más preciso un texto:

<xsl:text disable-output-escaping="yes"> 
    &lt;script src="jquery-2.0.3.js"&gt;&lt;/script&gt; 
</xsl:text> 

Btw. Creo que el método = "html" también debería ser el truco, pero no renderizará xhtml así, p. Ej. br no se cerrará

0

Otro truco rápida es añadir un comentario Javascript dentro de la etiqueta:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">//</script> 

Esto sólo tiene que añadir un comentario al final de la secuencia de comandos - tener cuidado de que usted no comentar nada por error, sin embargo!

Cuestiones relacionadas