Question

J'ai l'intention de mettre en œuvre le modèle d'affichage en deux étapes de Martin Fowler .  pour le rendu HTML dans une application Web que j'écris. L'idée générale est que, plutôt que de générer du code HTML brut, l'application génère un XML intermédiaire personnalisé, qui est ensuite converti en HTML / CSS. Ceci présente de nombreux avantages, notamment une duplication de code réduite et une sortie plus cohérente.

L’approche suggérée par Fowler pour convertir le code XML en HTML final consiste à utiliser XSLT.

J'ai déjà utilisé XSLT et je connais les bases. Cependant, je me demande quels sont les avantages de l’utilisation de XSLT. Une approche alternative que je considère ressemble à ceci:

Voici un exemple de sortie XML de la première étape de rendu:

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

Et la sortie HTML finale souhaitée:

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

L’approche envisagée aurait un objet pour chaque balise.

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

Les objets seraient construits dans un arbre en analysant le XML. La méthode render () serait appelée sur le nœud racine. J'aime particulièrement cette approche car elle me permet de faire des choses cool. En particulier, si j’ai une étiquette de cellule comme ci-dessus ou avec l’attribut type = & Quot; price & Quot:

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

La classe de balises qui lui est associée pourrait analyser le contenu de la balise pour séparer le symbole monétaire et la valeur numérique en balises HTML distinctes afin de permettre l'alignement du symbole monétaire et du point décimal, comme dans la sortie HTML ci-dessus.

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

Questions:

Dois-je faire cela ou devrais-je utiliser XSLT? Quels sont les avantages de l’utilisation de XSLT que je pourrais rater? Si je devais utiliser XSLT, comment puis-je analyser le contenu de l'étiquette de prix?

Était-ce utile?

La solution

Je ne peux pas vraiment dire grand-chose sur les raisons pour lesquelles vous devriez aller avec l'un ou l'autre.

Je pense que cela dépend énormément des détails techniques de votre processus de rendu, que vous souhaitiez que cela se produise sur le serveur ou sur le navigateur, de votre confort d'utilisation de XSLT ou, respectivement, de l'alternative à XSLT.

Un point pour XSLT est certainement qu'il est pratiquement impossible de générer une sortie XML qui n'est pas bien formée (je ne parle pas de valide ). Il est facile de rater quelque chose en écrivant des chaînes.

En ce qui concerne votre problème d’analyse: le meilleur moyen est sans aucun doute de séparer les données et le format dans le code XML. XSLT n'est pas destiné à l'analyse, je ne vois donc pas pourquoi votre code XML ne peut pas être dans ce format dès le début:

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

Cependant, si vous ne pouvez rien y faire, ce XSLT s'en occupera.

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

J'espère que vous pouvez voir pourquoi ce qui précède est essentiellement un mauvais code. Comparez l’alternative (si votre XML séparerait les données et le format):

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

Autres conseils

Le code que vous proposez présente quelques problèmes. Le plus important est que vous codez durement votre sortie pour qu'elle passe en sortie standard, ce qui rend plus difficile le post-traitement supplémentaire. Cela ne serait pas difficile à changer en modifiant votre méthode de rendu pour accepter un flux de sortie ou un écrivain.

Quoi qu’il en soit, vous proposez une tonne de code java qui implémentera essentiellement une transformation XSLT très spécifique. Il vaut mieux apprendre et utiliser XSLT pour transformer XML en HTML. L’avantage est que XSLT est un outil polyvalent conçu pour ce type de transformation.

Voici un exemple de XSLT qui fait presque ce que vous essayez de faire. J'ai malheureusement manqué de soucis à propos du temps où j'ai dû analyser la valeur monétaire dans les parties numérique et symbolique, mais cela suffit certainement pour vous aider à démarrer.

<?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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top