Pregunta

Digamos que estoy transformando un cuestionario de opción múltiple de un formato XML arbitrario a HTML. Cada opción se representará como una etiqueta HTML <li> en el documento de resultados. Para cada opción, quiero agregar un HTML class de correct a submitted si esa opción fue la respuesta correcta. Además, si esa opción fue la seleccionada por el usuario, quiero agregar una clase de correct submitted a <=>. En consecuencia, si la opción es la correcta y la presentada, la <=> debería tener un <=> de <=>.

Hasta donde yo sé, los valores de atributo 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. Sin embargo, tengo la sensación de que hay una mejor manera de hacerlo que ensuciando el código con un condicional para cada combinación posible 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 de 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>
¿Fue útil?

Solución

En primer lugar, no hay nada de malo con el espacio en blanco en los valores de los atributos en XML: en términos generales, normalización del valor del atributo convierte los espacios en blanco en espacios y contrae los espacios adyacentes en un solo espacio cuando se analiza un documento, pero el espacio en blanco definitivamente está 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 posibles valores, como usted menciona en su comentario al respecto. Sin embargo, su enfoque es fundamentalmente sólido. La pieza final del rompecabezas es su disgusto por los espacios redundantes: estos se pueden eliminar mediante el uso de la función normalize-space XPath.

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 la salida cumpla con su documento requisitos.

<?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>

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

Otros consejos

Fuera de mi cabeza, puedes construir 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>

Hasta donde yo sé, los valores de atributo 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 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!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top