Pregunta

Tengo la intención de implementar el Patrón de vista en dos pasos de Martin Fowler  para renderizar HTML en una aplicación web que estoy escribiendo. La idea general es que, en lugar de que la aplicación genere HTML sin formato, genera un XML intermedio personalizado que luego se convierte a HTML / CSS. Esto tiene una serie de ventajas que incluyen una duplicación de código reducida y una salida más consistente.

El enfoque sugerido por Fowler para convertir el XML al HTML final es usar XSLT.

He usado XSLT antes y sé lo básico. Sin embargo, me pregunto cuáles son las ventajas de usar XSLT. Un enfoque alternativo que estoy considerando se ve así:

Aquí hay un ejemplo de salida XML del primer paso de representación:

<grid>
   <headingRow>
      <cell>Product</cell>
      <cell>Price</cell>
   </headingRow>
   <row>
      <cell>A product</cell>
      <cell type="price">$54.95</cell>
   </row>
</grid>

Y la salida HTML final deseada:

<table class="grid">
  <tr>
    <th>Product</th>
    <th>Price</th>
  </tr>
  <tr>
    <td>A product</td>
    <td>
      <span class="currency_symbol">$</span>
      <span class="decimal_number">54.95</span>
    </td>
  </tr>
</table>

El enfoque que estoy considerando tendría un objeto para cada etiqueta.

class GridTag extends Tag {
  ...
  public void render() {
    System.out.println("<table class=\"grid\">");
    foreach(Tag child: children) {
      child.render();
    }
    System.out.println("</table>");
  }
  ...
}

Los objetos se construirían en un árbol analizando el XML. El método render () se llamaría en el nodo raíz. Particularmente me gusta este enfoque porque me permite hacer cosas geniales. Particularmente, si tengo una etiqueta de celda como la anterior con el atributo type = & Quot; price & Quot ;:

<cell type="price">$54.95</price>

Su clase de etiqueta asociada podría analizar el contenido de la etiqueta para separar el símbolo de moneda y el valor numérico en etiquetas HTML separadas para permitir la alineación del símbolo de moneda y el punto decimal, como en la salida HTML anterior.

<td>
  <span class="currency_symbol">$</span>
  <span class="decimal_number">54.95</span>
</td>

Preguntas:

¿Debo hacer esto o debo usar XSLT? ¿Cuáles son las ventajas de usar XSLT que podría perderme? Si debo usar XSLT, ¿cómo analizaré el contenido de la etiqueta de precio?

¿Fue útil?

Solución

Realmente no puedo decir mucho acerca de por qué deberías ir con uno u otro.

Creo que depende en gran medida de los detalles técnicos de su proceso de renderizado, ya sea que desee que suceda en el servidor o en el navegador, qué tan cómodo se sienta con XSLT o, respectivamente, la alternativa a XSLT.

Un punto para XSLT es que es prácticamente imposible generar una salida XML que no esté bien formada (no estoy hablando de válido ). Es fácil perderse algo al escribir cadenas.

Con respecto a su problema de análisis: sin lugar a dudas, la mejor manera es separar los datos y el formato directamente en el XML. XSLT no es para analizar, por lo que no veo por qué su XML no puede estar en este formato desde el principio:

<cell type="price" symbol="$">54.95</cell>

Sin embargo, suponiendo que no pueda hacer nada al respecto, este XSLT se encargaría de ello.

<xsl:template match="cell[@type='price']">
  <td>
    <xsl:variable name="vNonNumbers" select="translate(., '0123456789.', '')" />
    <xsl:variable name="vTheNumbers" select="translate(., $vNonNumbers, '')" />
    <span class="currency_symbol">
      <xsl:value-of select="$vNonNumbers" />
    </span>
    <span class="decimal_number">
      <xsl:value-of select="$vTheNumbers" />
    </span>
  </td>
</xsl:template>

Espero que puedan ver por qué lo anterior es esencialmente un código incorrecto. Compare con la alternativa (si su XML separaría datos y formato):

<xsl:template match="cell[@type='price']">
  <td>
    <span class="currency_symbol">
      <xsl:value-of select="@symbol" />
    </span>
    <span class="decimal_number">
      <xsl:value-of select="." />
    </span>
  </td>
</xsl:template>

Otros consejos

El código que está proponiendo tiene algunos problemas. Lo más importante es que está codificando su salida para que salga al estándar, lo que hace que sea más difícil realizar un procesamiento posterior adicional. Esto no sería difícil de cambiar modificando su método de renderizado para aceptar una secuencia de salida o escritor.

Sin embargo, lo que está proponiendo es una tonelada de código java que básicamente implementará una transformación XSLT muy específica. Es mucho mejor que solo aprenda y use XSLT para transformar XML en HTML. La ventaja es que XSLT es una herramienta de propósito general diseñada para exactamente este tipo de transformación.

Aquí hay un ejemplo de XSLT que casi hace lo que intentas hacer. Desafortunadamente, me quedé sin cares justo sobre el momento en que tuve que analizar el valor de la moneda en las partes numéricas y simbólicas, pero esto es sin duda suficiente para comenzar.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/grid">
    <table class="grid">
      <xsl:apply-templates select="headingRow"/>
      <xsl:apply-templates select="row"/>
    </table>
  </xsl:template>
  <xsl:template match="headingRow">
      <tr>
        <xsl:apply-templates select="cell" mode="heading"/>
      </tr>
  </xsl:template>
  <xsl:template match="row">
      <tr>
        <xsl:apply-templates select="cell" mode="normal"/>
      </tr>
  </xsl:template>  
  <xsl:template match="cell" mode="heading">
    <th><xsl:value-of select="."/></th>
  </xsl:template>

  <xsl:template match="cell" mode="normal">
    <xsl:choose>
      <xsl:when test="@type='price'">
        <td>
          <span class="currency_symbol">
            <xsl:value-of select="." />
          </span>
          <span class="decimal_number">
            <xsl:value-of select="." />
          </span>
        </td>
      </xsl:when>
      <xsl:otherwise>
        <td>
          <xsl:value-of select="." />
        </td>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top