Voici mon exemple artificiel qui illustre ce que je tente d'accomplir. J'ai un fichier XML d'entrée que je souhaite aplatir pour un traitement ultérieur.Réutilisation du modèle XSL à appeler avec différents XPath relatifs
fichier d'entrée:
<BICYCLES>
<BICYCLE>
<COLOR>BLUE</COLOR>
<WHEELS>
<WHEEL>
<WHEEL_TYPE>FRONT</WHEEL_TYPE>
<FLAT>NO</FLAT>
<REFLECTORS>
<REFLECTOR>
<REFLECTOR_NUM>1</REFLECTOR_NUM>
<SHAPE>SQUARE</SHAPE>
</REFLECTOR>
<REFLECTOR>
<REFLECTOR_NUM>2</REFLECTOR_NUM>
<SHAPE>ROUND</SHAPE>
</REFLECTOR>
</REFLECTORS>
</WHEEL>
<WHEEL>
<WHEEL_TYPE>REAR</WHEEL_TYPE>
<FLAT>NO</FLAT>
</WHEEL>
</WHEELS>
</BICYCLE>
</BICYCLES>
L'entrée est une liste de noeuds <BICYCLE>
. Chaque <BICYCLE>
a une <COLOR>
et a en option <WHEELS>
.
<WHEELS>
est une liste de noeuds <WHEEL>
, chacun d'entre eux ayant quelques attributs et ayant éventuellement la valeur <REFLECTORS>
.
<REFLECTORS>
est une liste de nœuds <REFLECTOR>
, chacun ayant quelques attributs.
L'objectif est d'aplatir ce XML. C'est le XSL J'utilise:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" xml:space="preserve"/>
<xsl:template match="/">
<BICYCLES>
<xsl:apply-templates/>
</BICYCLES>
</xsl:template>
<xsl:template match="BICYCLE">
<xsl:choose>
<xsl:when test="WHEELS">
<xsl:apply-templates select="WHEELS"/>
</xsl:when>
<xsl:otherwise>
<BICYCLE>
<COLOR><xsl:value-of select="COLOR"/></COLOR>
<WHEEL_TYPE/>
<FLAT/>
<REFLECTOR_NUM/>
<SHAPE/>
</BICYCLE>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="WHEELS">
<xsl:apply-templates select="WHEEL"/>
</xsl:template>
<xsl:template match="WHEEL">
<xsl:choose>
<xsl:when test="REFLECTORS">
<xsl:apply-templates select="REFLECTORS"/>
</xsl:when>
<xsl:otherwise>
<BICYCLE>
<COLOR><xsl:value-of select="../../COLOR"/></COLOR>
<WHEEL_TYPE><xsl:value-of select="WHEEL_TYPE"/></WHEEL_TYPE>
<FLAT><xsl:value-of select="FLAT"/></FLAT>
<REFLECTOR_NUM/>
<SHAPE/>
</BICYCLE>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="REFLECTORS">
<xsl:apply-templates select="REFLECTOR"/>
</xsl:template>
<xsl:template match="REFLECTOR">
<BICYCLE>
<COLOR><xsl:value-of select="../../../../COLOR"/></COLOR>
<WHEEL_TYPE><xsl:value-of select="../../WHEEL_TYPE"/></WHEEL_TYPE>
<FLAT><xsl:value-of select="../../FLAT"/></FLAT>
<REFLECTOR_NUM><xsl:value-of select="REFLECTOR_NUM"/></REFLECTOR_NUM>
<SHAPE><xsl:value-of select="SHAPE"/></SHAPE>
</BICYCLE>
</xsl:template>
</xsl:stylesheet>
La sortie est:
<BICYCLES xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<BICYCLE>
<COLOR>BLUE</COLOR>
<WHEEL_TYPE>FRONT</WHEEL_TYPE>
<FLAT>NO</FLAT>
<REFLECTOR_NUM>1</REFLECTOR_NUM>
<SHAPE>SQUARE</SHAPE>
</BICYCLE>
<BICYCLE>
<COLOR>BLUE</COLOR>
<WHEEL_TYPE>FRONT</WHEEL_TYPE>
<FLAT>NO</FLAT>
<REFLECTOR_NUM>2</REFLECTOR_NUM>
<SHAPE>ROUND</SHAPE>
</BICYCLE>
<BICYCLE>
<COLOR>BLUE</COLOR>
<WHEEL_TYPE>REAR</WHEEL_TYPE>
<FLAT>NO</FLAT>
<REFLECTOR_NUM/>
<SHAPE/>
</BICYCLE>
</BICYCLES>
Ce que je n'aime pas à ce sujet est que je suis sortie l'attribut de couleur sous plusieurs formes:
Il semble qu'il devrait y avoir un moyen de créer un modèle nommé et de l'invoquer à partir des divers endroits où il est nécessaire, et de passer un paramètre qui représente le chemin vers le nœud <BICYCLE>
ch il se réfère.
Y a-t-il un moyen de nettoyer cela, disons avec un gabarit nommé pour les champs de bicyclette, pour les champs de roues et pour les champs de réflecteurs? Dans l'exemple réel sur lequel il est basé, il y a beaucoup plus d'attributs à un "vélo" que juste la couleur, et je veux que ce XSL soit facile à changer pour inclure ou exclure des champs sans avoir à changer le XSL dans plusieurs endroits.
Mais le chemin était-il dans le modèle? Si je mets , il ne trouvera pas la couleur si le template est invoqué depuis le template REFECTOR. –
user189169
@meomaxy Semble que vous voulez un [axe] différent (http://www.w3schools.com/xpath/xpath_axes.asp), probablement 'ancestor'. Quelque chose comme 'ancestor :: bicycle/color'? –
OUI !!! ancestor-or-self :: BICYCLETTE/COULEUR MERCI! – user189169