Cela sonne comme devoirs :-)
Vous travaillez avec 2 choses ici:
- éléments Arbitrairement nommés que vous devez appliquer un modèle XSLT, et
- Déterminer quel type du contenu d'un élément (texte ou fragment XML).
Vous souhaitez utiliser un modèle qui peut correspondre arbitrairement à des éléments de votre fichier XML (c'est-à-dire pas des éléments avec un nom spécifique). <xsl:template match="*">
correspond à tous les éléments de votre document XML.
Lorsque vous rencontrez un élément, vous devez créer une table:
<xsl:template match="*">
<table border="1px">
</table>
</xsl:template>
Maintenant, nous voulons travailler si nous avons affaire à un fragment XML (un élément) ou un morceau de texte. Pour ce faire, nous faisons correspondre node()
. Rappelez-vous qu'un nœud peut être un élément, un texte, un espace, une instruction de traitement ou un commentaire dans un document XML. Lorsque vous avez un nœud jumelé, vous souhaitez créer une nouvelle ligne de table et d'afficher le nom du noeud courant:
<xsl:template match="node()">
<tr>
<td>
<xsl:value-of select="local-name()"/>
</td>
</tr>
</xsl:template>
Vous devez ensuite travailler si le nœud est un nœud de texte ou non. Vous pouvez utiliser un <xsl:if>
ou un <xsl:choose>
. J'ai tendance à préférer ce dernier. S'il s'agit d'un nœud de texte, affichez la valeur du texte, sinon traitez le nœud comme un fragment XML et appelez à nouveau notre modèle initial (ceci est la partie récursive).
...
<xsl:choose>
<xsl:when test="current() = text()">
<td>
<xsl:value-of select="." />
</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:apply-templates select="*" mode="table"/>
</td>
</xsl:otherwise>
</xsl:choose>
...
est ici la solution finale.
<xsl:template match="/root">
<xsl:apply-templates select="*" mode="table" />
</xsl:template>
<xsl:template match="*" mode="table">
<table border="1px">
<xsl:apply-templates select="." mode="table-row" />
</table>
</xsl:template>
<xsl:template match="node()" mode="table-row">
<tr>
<td>
<xsl:value-of select="local-name()"/>
</td>
<xsl:choose>
<xsl:when test="current() = text()">
<td>
<xsl:value-of select="." />
</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:apply-templates select="*" mode="table"/>
</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:template>
J'utilise l'attribut mode
sur le modèle parce qu'un élément est également un noeud dans un document XML et <xsl:apply-templates select="*"/>
vous trouverez aussi bien <xsl:template match="*">
ainsi que <xsl:template match="node()">
. L'utilisation de l'attribut mode
supprime l'ambiguïté.
Bonne question, +1. Voyez ma solution pour une solution XSLT courte et très puissante, tout à fait dans l'esprit de XSLT. :) –