2009-10-26 18 views
6

Digamos que estoy transformando un cuestionario de opción múltiple de un formato XML arbitrario a HTML. Cada elección se representará como una etiqueta HTML <li> en el documento de resultados. Para cada opción, deseo agregar un HTML class de correct al <li> si esa elección fue la respuesta correcta. Además, si esa opción fue la seleccionada por el usuario, quiero agregar una clase de submitted al <li>. En consecuencia, si la elección es la correcta , así como la presentada, el <li> debe tener un class de correct submitted.¿Existe una forma elegante de agregar múltiples clases de HTML con XSLT?

Por lo que sé, los valores de los atributos de espacios en blanco no son parte del modelo de datos XML y, por lo tanto, no se pueden crear directamente a través de XSLT. Sin embargo, tengo la sensación de que hay una forma mejor de hacerlo que ensuciar el código con un condicional para cada posible combinación de clases (lo que sería aceptable en este ejemplo, pero difícil de manejar en escenarios más complejos).

¿Cómo puedo resolver esto de una manera elegante?

Ejemplo del resultado deseado:

<p>Who trained Obi-Wan Kenobi?</p> 
<ul> 
    <li>Mace Windu</li> 
    <li class="correct submitted">Qui-Gon Jinn</li> 
    <li>Ki-Adi-Mundi</li> 
    <li>Yaddle</li> 
</ul> 

Respuesta

9

En primer lugar, no hay nada de malo con el espacio en valores de atributo en XML: aproximadamente, attribute value normalization convierte espacios en espacios y colapsa espacios adyacentes a un espacio único cuando se analiza un documento, pero el espacio en blanco está definitivamente permitido. EDITAR: Consulte a continuación para obtener más información al respecto.

El enfoque de Matthew Wilson no incluye espacios en blanco entre los valores posibles, como usted menciona en su comentario al respecto. Sin embargo, su enfoque es fundamentalmente sólido. La última pieza del rompecabezas es su desagrado por los espacios redundantes: estos pueden eliminarse mediante el uso de la función XPath normalize-space.

La siguiente hoja de estilo reúne todos los bits, tenga en cuenta que no hace nada con su documento de entrada, por lo que para fines de prueba puede ejecutarlo contra cualquier documento XML, o incluso contra sí mismo, para verificar que el resultado tus requerimientos

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:variable name="foo0" select="false()"/> 
    <xsl:variable name="bar0" select="true()"/> 

    <xsl:variable name="foo1" select="true()"/> 
    <xsl:variable name="bar1" select="false()"/> 

    <xsl:variable name="foo2" select="true()"/> 
    <xsl:variable name="bar2" select="true()"/> 

    <xsl:template match="/"> 

    <xsl:variable name="foobar0"> 
     <xsl:if test="$foo0"> foo</xsl:if> 
     <xsl:if test="$bar0"> bar</xsl:if> 
    </xsl:variable> 

    <xsl:variable name="foobar1"> 
     <xsl:if test="$foo1"> foo</xsl:if> 
     <xsl:if test="$bar1"> bar</xsl:if> 
    </xsl:variable> 

    <xsl:variable name="foobar2"> 
     <xsl:if test="$foo2"> foo</xsl:if> 
     <xsl:if test="$bar2"> bar</xsl:if> 
    </xsl:variable> 

    <li> 
     <xsl:attribute name="class"> 
     <xsl:value-of select="normalize-space($foobar0)"/> 
     </xsl:attribute> 
    </li> 
    <li> 
     <xsl:attribute name="class"> 
     <xsl:value-of select="normalize-space($foobar1)"/> 
     </xsl:attribute> 
    </li> 
    <li> 
     <xsl:attribute name="class"> 
     <xsl:value-of select="normalize-space($foobar2)"/> 
     </xsl:attribute> 
    </li> 

    </xsl:template> 
</xsl:stylesheet> 

EDIT: Además de la cuestión de los espacios que separan los componentes discretos dentro del valor de un atributo: la especificación XML define un número de posibles construcciones válidos como attribute types, incluyendo IDREFS y NMTOKENS. El primer caso coincide con la producción Names, y el segundo caso coincide con la producción NMTokens; Ambas producciones se definen como que contienen valores múltiples del tipo apropiado, delimitados por espacios.Por lo tanto, las listas de valores delimitadas por espacios como el valor de un solo atributo son un componente inherente del conjunto de información XML.

+0

En realidad, mi punto acerca de los valores de los atributos separados por espacios en blanco es que XML no los reconoce como valores distintos: es una sola cadena larga (a menos que haya pasado por alto alguna parte de XML). Esa es la razón por la que siempre me siento un poco sucio cuando uso atributos de clase para empezar. Dicho esto, me doy cuenta de que es mucho más fácil para nosotros los programadores separar las clases con espacios en lugar de meter en un grupo de elementos secundarios '' en todas partes. – Jakob

+2

@Jakob: He agregado algunos detalles más sobre las listas de valores separadas por espacios que forman un único valor de atributo al final de mi respuesta. – NickFitz

5

De la parte superior de la cabeza, puede crear una lista separada por espacios con algo como:

<li> 
    <xsl:attribute name="class"> 
     <xsl:if cond="...">correct</xsl:if> 
     <xsl:if cond="...">submitted</xsl:if> 
    </xsl:attribute> 
</li> 
+0

Eso no funciona (al menos no usa PHP). No hay espacio en blanco aparte de lo que rodea a los elementos 'if', y eso no afecta el resultado (para eso, necesitaría usar elementos' text'). De acuerdo, podría usar esta solución y simplemente agregar un espacio después de cada posible nombre de clase, pero eso llevaría a espacios redundantes y parecería más desordenado de lo que debería ser necesario. – Jakob

+1

Lo he usado con éxito, así que tal vez sea una diferencia en los procesadores XSLT en cuanto a lo que hacen con los espacios en blanco en el archivo XSLT mismo. –

+2

¿No debería 'cond' ser' prueba'? – Maarten

1

Por lo que yo saber, los valores de los atributos separados por espacios en blanco no son parte del modelo de datos XML y, por lo tanto, no se pueden crear directamente a través de XSLT

A menos que esté convirtiendo a un lenguaje XML (que HTML no lo es, XHTML es), no debe preocuparse por la validez XML de la salida XSLT . ¡Esto puede ser cualquier cosa, y no necesita ajustarse a XML!

+0

No estoy diciendo que los valores de los atributos separados por espacios en blanco sean XML no válidos, solo que no hay (que yo sepa) construcciones XSLT que los generen específicamente. – Jakob

Cuestiones relacionadas