2012-03-01 8 views
6

Así que traté de investigar esto y estoy casi en mi ingenio. Encontré una manera de insertar XSL en XML en dpawson.co.uk, pero no puedo entender lo que estoy haciendo mal. He buscado en Internet tratando de encontrar soluciones y explicaciones, pero nadie parece tener una respuesta.Incrustar XSL en XML para mostrar en el navegador web: ¿Qué estoy haciendo mal?

Estoy tratando de crear un archivo que sea independiente del servidor para que pueda enviar un archivo a mis colegas con la esperanza de que puedan ver el archivo abriéndolo en su navegador web.

Aquí está mi código hasta ahora:

<?xml version="1.0" encoding="ISO-8859-1"?> 

<!--Start XSL--> 

<?xml-stylesheet type="text/xml" href="#stylesheet"?> 

<!DOCTYPE doc [ 
<!ATTLIST xsl:stylesheet 
id ID #REQUIRED> 
]> 
<doc> 

<xsl:stylesheet id="stylesheet" 
       version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 
<xsl:template match="xsl:stylesheet" /> 
    <!--Variables--> 
    <xsl:variable name="a" select="list/movie/seen[@value ='Yes']" /> 
    <xsl:variable name="b" select="list/movie/seen" /> 
    <xsl:variable name="c" select="sum(list/movie/rating/@value)" /> 
    <xsl:variable name="d" select="$c div count($a)" /> 
    <xsl:variable name="e" select="count($a) div count($b)" /> 
    <xsl:variable name="f" select="list/movie/seen[@value ='No']" /> 
    <xsl:variable name="g" select="list/movie/seen[@value ='Prior']" /> 
    <xsl:variable name="h" select="count($f) div count($b)" /> 
    <xsl:variable name="j" select="count($g) div count($b)" /> 
    <xsl:variable name="minutes_total" select="sum(list/movie/length[@value ='y'])" /> 
    <xsl:variable name="minutes" select="$minutes_total mod 60" /> 
    <xsl:variable name="hours" select="floor($minutes_total div 60) mod 24" /> 
    <xsl:variable name="hours2" select="floor($minutes_total div 60)" /> 
    <xsl:variable name="days" select="floor($hours2 div 24)" /> 
    <xsl:decimal-format name="percent" /> 
    <xsl:decimal-format name="average" decimal-separator="." /> 
    <!--End Variables--> 
    <xsl:template match="/doc"> 
     <html> 
      <head> 
       <style> 
        h2{ 
        font-family: Courier, Courier New, monospace; 
        font-size: 32px; 
        text-decoration: underline; 
        } 
        body{ 
        font-family: Courier New, monospace; 
        } 
        p{ 
        font-size: 16px; 
        } 
        table{ 
        font-size: 14px; 
        } 
        .title{ 
        text-align:left; 
        } 
        .release{ 
        text-align:center; 
        } 
        .seen{ 
        text-align:center; 
        } 
        .rating{ 
        text-align:right; 
        } 
        .length{ 
        text-align:center; 
        } 
       </style> 
      </head> 
      <body> 
       <h2>My Movie List</h2> 
       <p>Movies seen so far: <xsl:value-of select="count($a)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($e, '#%', 'percent')" /><br /> 
       Movies yet to see: <xsl:value-of select="count($f)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($h, '#%', 'percent')" /><br /> 
       Movies seen prior to making list: <xsl:value-of select="count($g)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($j, '#%', 'percent')" /><br /> 
       Total time watched: <xsl:value-of select="format-number($days, '#0')" /> days, <xsl:value-of select="format-number($hours, '#0')" /> hours, <xsl:value-of select="format-number($minutes, '#0')" /> minutes<br /> 
       Average rating: <xsl:value-of select="format-number($d, '#.000', 'average')" /> stars out of 5</p> 
       <br /> 
       <table border="1"> 
        <tr> 
         <th>#</th> 
         <th>Title</th> 
         <th>Release Date</th> 
         <th>Length</th> 
         <th>Seen</th> 
         <th>Rating</th> 
        </tr> 
        <xsl:for-each select="list/movie"> 
         <xsl:choose> 
          <xsl:when test='seen = "Yes"'> 
           <tr style="background-color:#666; color:#fff"> 
            <td> <xsl:number /></td> 
            <td class="title"><xsl:value-of select="title"/></td> 
            <td class="release"><xsl:value-of select="release"/></td> 
            <td class="length"><xsl:value-of select="length" /> minutes</td> 
            <td class="seen"><xsl:value-of select="seen"/></td> 
            <td class="rating"><xsl:value-of select="rating"/></td> 
           </tr> 
          </xsl:when> 
          <xsl:when test='seen = "Seen prior to making list"'> 
           <tr style="background-color:#999; color:#000"> 
            <td> <xsl:number /></td> 
            <td class="title"><xsl:value-of select="title"/></td> 
            <td class="release"><xsl:value-of select="release"/></td> 
            <td class="length"><xsl:value-of select="length"/> minutes</td> 
            <td class="seen"><xsl:value-of select="seen"/></td> 
            <td class="rating"><xsl:value-of select="rating"/></td> 
           </tr> 
          </xsl:when> 
          <xsl:otherwise> 
           <tr style="background-color:#fff;"> 
            <td> <xsl:number /></td> 
            <td class="title"><xsl:value-of select="title"/></td> 
            <td class="release"><xsl:value-of select="release"/></td> 
            <td class="length"><xsl:value-of select="length" /> minutes</td> 
            <td class="seen"><xsl:value-of select="seen"/></td> 
            <td class="rating"><xsl:value-of select="rating"/></td> 
           </tr> 
          </xsl:otherwise> 
         </xsl:choose> 
        </xsl:for-each> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 
<!--Start XML--> 
<list> 
    <movie> 
     <title>2001: A Space Odyssey</title> 
     <release>1968</release> 
     <seen value="No">No</seen> 
     <rating>N/A</rating> 
     <length value="n">141</length> 
    </movie> 
    <movie> 
     <title>28 Days Later</title> 
     <release>2002</release> 
     <seen value="No">No</seen> 
     <rating>N/A</rating> 
     <length value="n">113</length> 
    </movie> 
    <movie> 
     <title>28 Weeks Later</title> 
     <release>2007</release> 
     <seen value="No">No</seen> 
     <rating>N/A</rating> 
     <length value="n">100</length> 
    </movie> 
    <movie> 
     <title>A Clockwork Orange</title> 
     <release>1971</release> 
     <seen value="Yes">Yes</seen> 
     <rating value="2">&#9734;&#9734;&#9734;&#9733;&#9733;</rating> 
     <length value="y">136</length> 
    </movie> 
<!--Rest of XML--> 
</list> 
</doc> 

Es una lista de películas que contiene el número que he visto hasta ahora, ¿cuántos todavía tengo que ver, ¿cuántos he visto antes hice la lista, la cantidad total de tiempo que he dedicado a ver películas y la calificación promedio por película vista.

El problema es que todas las variables se muestran con valor cero, lo que causa dividir por ceros, lo que da valor de NaN en algunos de los resultados también.

¡Cualquier cosa que cualquier persona pueda ofrecer sería muy apreciada!

+0

Realmente no entiendo lo que estás tratando de hacer aquí, pero no creo que esto sea una hoja de estilo. Su etiqueta está incrustada dentro de una etiqueta que es muy extraña – Kevan

+0

Desafortunadamente, mi XML era demasiado grande para caber completamente en el cuerpo de la pregunta. Lo que trato de hacer es hacer que mis variables funcionen. Cuando tengo los archivos .xml y .xsl separados, funciona muy bien. Pero cuando incrusto, aparece el xml, pero mis variables no funcionan. Obtuve muchos 0 y NaN. – ishmael624

+1

¿Qué estás haciendo con este documento? Usted dice "aparece el xml". ¿Dónde? ¿Qué software está ejecutando, y cómo? –

Respuesta

8

El siguiente código:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<?xml-stylesheet type="text/xsl" href="#stylesheet"?> 
<!DOCTYPE doc [ 
<!ATTLIST xsl:stylesheet 
id ID #REQUIRED> 
]> 
<doc> 
<!--Start XSL--> 
<xsl:stylesheet id="stylesheet" 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 

    <xsl:template match="xsl:stylesheet" /> 

    <!--Variables--> 
    <xsl:variable name="a" select="/doc/list/movie/seen[@value ='Yes']" /> 
    <xsl:variable name="b" select="/doc/list/movie/seen" /> 
    <xsl:variable name="c" select="sum(/doc/list/movie/rating/@value)" /> 
    <xsl:variable name="d" select="$c div count($a)" /> 
    <xsl:variable name="e" select="count($a) div count($b)" /> 
    <xsl:variable name="f" select="/doc/list/movie/seen[@value ='No']" /> 
    <xsl:variable name="g" select="/doc/list/movie/seen[@value ='Prior']" /> 
    <xsl:variable name="h" select="count($f) div count($b)" /> 
    <xsl:variable name="j" select="count($g) div count($b)" /> 
    <xsl:variable name="minutes_total" select="sum(/doc/list/movie/length[@value ='y'])" /> 
    <xsl:variable name="minutes" select="$minutes_total mod 60" /> 
    <xsl:variable name="hours" select="floor($minutes_total div 60) mod 24" /> 
    <xsl:variable name="hours2" select="floor($minutes_total div 60)" /> 
    <xsl:variable name="days" select="floor($hours2 div 24)" /> 
    <!--End Variables--> 

    <xsl:decimal-format name="percent" /> 
    <xsl:decimal-format name="average" decimal-separator="." /> 

    <xsl:template match="/doc"> 
    <html> 
    <head> 
    <style> 
     h2{ 
     font-family: Courier, Courier New, monospace; 
     font-size: 32px; 
     text-decoration: underline; 
     } 
     body{ 
     font-family: Courier New, monospace; 
     } 
     p{ 
     font-size: 16px; 
     } 
     table{ 
     font-size: 14px; 
     } 
     .title{ 
     text-align:left; 
     } 
     .release{ 
     text-align:center; 
     } 
     .seen{ 
     text-align:center; 
     } 
     .rating{ 
     text-align:right; 
     } 
     .length{ 
     text-align:center; 
     } 
    </style> 
    </head> 
    <body> 
    <h2>My Movie List</h2> 
    <p>Movies seen so far: <xsl:value-of select="count($a)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($e, '#%', 'percent')" /><br /> 
    Movies yet to see: <xsl:value-of select="count($f)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($h, '#%', 'percent')" /><br /> 
    Movies seen prior to making list: <xsl:value-of select="count($g)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($j, '#%', 'percent')" /><br /> 
    Total time watched: <xsl:value-of select="format-number($days, '#0')" /> days, <xsl:value-of select="format-number($hours, '#0')" /> hours, <xsl:value-of select="format-number($minutes, '#0')" /> minutes<br /> 
    Average rating: <xsl:value-of select="format-number($d, '#.000', 'average')" /> stars out of 5</p> 
    <br /> 
    <table border="1"> 
     <tr> 
     <th>#</th> 
     <th>Title</th> 
     <th>Release Date</th> 
     <th>Length</th> 
     <th>Seen</th> 
     <th>Rating</th> 
     </tr> 
     <xsl:for-each select="list/movie"> 
     <xsl:choose> 
     <xsl:when test='seen = "Yes"'> 
     <tr style="background-color:#666; color:#fff"> 
      <td> <xsl:number /></td> 
      <td class="title"><xsl:value-of select="title"/></td> 
      <td class="release"><xsl:value-of select="release"/></td> 
      <td class="length"><xsl:value-of select="length" /> minutes</td> 
      <td class="seen"><xsl:value-of select="seen"/></td> 
      <td class="rating"><xsl:value-of select="rating"/></td> 
     </tr> 
     </xsl:when> 
     <xsl:when test='seen = "Seen prior to making list"'> 
     <tr style="background-color:#999; color:#000"> 
      <td> <xsl:number /></td> 
      <td class="title"><xsl:value-of select="title"/></td> 
      <td class="release"><xsl:value-of select="release"/></td> 
      <td class="length"><xsl:value-of select="length"/> minutes</td> 
      <td class="seen"><xsl:value-of select="seen"/></td> 
      <td class="rating"><xsl:value-of select="rating"/></td> 
     </tr> 
     </xsl:when> 
     <xsl:otherwise> 
     <tr style="background-color:#fff;"> 
      <td> <xsl:number /></td> 
      <td class="title"><xsl:value-of select="title"/></td> 
      <td class="release"><xsl:value-of select="release"/></td> 
      <td class="length"><xsl:value-of select="length" /> minutes</td> 
      <td class="seen"><xsl:value-of select="seen"/></td> 
      <td class="rating"><xsl:value-of select="rating"/></td> 
     </tr> 
     </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 
    </table> 
    </body> 
    </html> 
    </xsl:template> 
</xsl:stylesheet> 

<!--Start XML--> 
<list> 
    <movie> 
    <title>2001: A Space Odyssey</title> 
    <release>1968</release> 
    <seen value="No">No</seen> 
    <rating>N/A</rating> 
    <length value="n">141</length> 
    </movie> 
    <movie> 
    <title>28 Days Later</title> 
    <release>2002</release> 
    <seen value="No">No</seen> 
    <rating>N/A</rating> 
    <length value="n">113</length> 
    </movie> 
    <movie> 
    <title>28 Weeks Later</title> 
    <release>2007</release> 
    <seen value="No">No</seen> 
    <rating>N/A</rating> 
    <length value="n">100</length> 
    </movie> 
    <movie> 
    <title>A Clockwork Orange</title> 
    <release>1971</release> 
    <seen value="Yes">Yes</seen> 
    <rating value="2">&#9734;&#9734;&#9734;&#9733;&#9733;</rating> 
    <length value="y">136</length> 
    </movie> 
    <!--Rest of XML--> 
</list> 
</doc> 

produce el resultado deseado como se muestra a continuación cuando se guarda como un archivo XML y abierto en el navegador web Firefox. El formateo no se muestra aquí, pero lo será cuando abra un archivo XML que contenga el código anterior en FireFox.

My Movie List 

Movies seen so far: 1/4 = 25% 
Movies yet to see: 3/4 = 75% 
Movies seen prior to making list: 0/4 = 0% 
Total time watched: 0 days, 2 hours, 16 minutes 
Average rating: 2.000 stars out of 5 

# Title   Release Date Length  Seen Rating 
1 2001: A Space Odyssey 1968 141 minutes No  N/A 
2 28 Days Later   2002 113 minutes No  N/A 
3 28 Weeks Later  2007 100 minutes No  N/A 
4 A Clockwork Orange 1971 136 minutes Yes  ☆☆☆★★ 

Nota 1: El problema fue el cambio de nivel de elemento de anidación causada por la incorporación del XML<list>dentro del elemento<doc>cuando se pone el XML y XSL en el formato de archivo único. La solución agrega /doc antes /list en todas sus expresiones XPath con el fin de seleccionar los elementos deseados que ahora están anidados un nivel más profundo como descendientes de <doc>y<list> en lugar de sólo los descendientes de <list> (como lo eran cuando los dos archivos eran separar).

Nota 2: tipo xml-stylesheet también fue cambiado a "text/xsl" como un paso hacia la compatibilidad con IE 8. Con el tipo "text/xml", IE 8 sólo muestra la estructura del documento (incluyendo XSL) como XML, mientras que con "text/xsl" intenta, aunque sin éxito, aplicar la transformación. Se necesitaría más trabajo para hacer que esta visualización sea correcta en IE 8. Tenga en cuenta que cualquiera de los valores de tipo funciona bien en FireFox 7. No se probaron otros navegadores.

+0

¡Muchas gracias! Estaba totalmente perdido con este problema, pero tu solución ayudó mucho. Gracias, Witman! – ishmael624

+0

@SamuelPearseWalters: De nada; ¡me alegro de poder ayudar! – Witman

+2

Actualización rápida: la solución funciona bien en Chrome 29 y Firefox 23. No funcionó en IE10 (en caso de que alguien quiera saber) –

Cuestiones relacionadas