From: Frédéric Laurent (fl@opikanoba.org)
Date: 06/05/2004 - 22:16
PHDB _ wrote:
> Bonjour,
bonjour
>
> question d'un gros newbie en XSLT :
et en XML :)
Préambule :
<Champ 1> n'est pas une balise valide !
l'espace n'est pas autorisé dans le nom des éléments XML
voir la spécification XML, rubrique Name [1]
>
> Est-ce possible en appliquant une XSL d'effectuer des conversions sur des
> champs XML pour recreer un nouvel XML avec les valeurs converties.
oui !
tout dépend après de la complexité de la conversion. Pour celles
présentées ci dessous, xslt suffit
>
> Un exemple valant mieux qu'un long discours, admettons que j'aie
> <Racine>
> <Fils ID="214">
> <Champ 1>X</Champ 1>
> <Champ 2>14</Champ 2>
> </Fils>
> </Racine>
>
> et que je veuille obtenir
> <Racine>
> <Fils ID="214">
> <Champ 1>true</Champ 1>
> <Champ 2>00014</Champ 2>
> </Fils>
> </Racine>
>
> A savoir transformer la valeur du 'Champ 1' de X/Y en true/false et "padder"
> la valeur du 'Champ 2' a 5 numeriques (cad convertir 1 en 00001, 124 en
> 00124).
> Est-ce possible a faire via XSLT en appelant des fonctions de conversion
> adequates par exemple ?
> Si oui de quelle facon ?
reprenons un XML valide donc
<?xml version="1.0"?>
<Racine>
<Fils ID="214">
<Champ1>X</Champ1>
<Champ2>14</Champ2>
<Champ3>Y</Champ3>
<champ4>toto</champ4>
<Champ5>1</Champ5>
</Fils>
</Racine>
Le principe :
- tous les éléments sont copiés sur l'arbre de sortie via la
transformation identité, voir le message de Benoit Lefevre pour
les précisions [2]
- le texte des éléments est à analyser.
Un <xsl:choose> fait l'affaire, il y a plusieurs cas simples
1. <xsl:when test=".='X'">true</xsl:when>
2. <xsl:when test=".='Y'">false</xsl:when>
3. <xsl:when test="normalize-space(.)=''">
<xsl:value-of select="."/>
</xsl:when>
Ce qui revient à recopier les espaces, retours chariots...
4. le cas par défaut
<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
et puis un cas plus complexe : mon texte est-il un nombre ?
si oui, on le formate via format-number() [3]
<xsl:when test="string(number()) != 'NaN'">
<xsl:value-of select="format-number(.,'00000')"/>
</xsl:when>
et voila le tour est joué.
A noter que number(.) vaut 'NaN' si . n'est pas un nombre
Mais number(.)!='NaN' est toujours vrai, ce qui
revient à dire que 'NaN' n'est pas égal à 'NaN'...
il faut utiliser la fonction string() pour comparer les
deux chaines de caractères [4]
Donc la feuille de style complète
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="text()" priority="0">
<xsl:choose>
<xsl:when test=".='X'">true</xsl:when>
<xsl:when test=".='Y'">false</xsl:when>
<xsl:when test="normalize-space(.)=''">
<xsl:value-of select="."/></xsl:when>
<xsl:when test="string(number()) != 'NaN'">
<xsl:value-of select="format-number(.,'00000')"/>
</xsl:when>
<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*|@*|processing-instruction()|text()">
<xsl:copy>
<xsl:apply-templates
select="*|@*|processing-instruction()|text()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
qui donne bien
<?xml version="1.0" encoding="UTF-8"?>
<Racine>
<Fils ID="214">
<Champ1>true</Champ1>
<Champ2>00014</Champ2>
<Champ3>false</Champ3>
<champ4>toto</champ4>
<Champ5>00001</Champ5>
</Fils>
</Racine>
[1] http://www.w3.org/TR/REC-xml/#NT-Name
[2] http://xmlfr.org/listes/xml-tech/2004/05/0049.html
[2] http://www.w3.org/TR/xslt.html#format-number
[3] http://www.dpawson.co.uk/xsl/sect2/N5846.html
cordialement
Frédéric Laurent
--
XPath free testing software : http://www.opikanoba.org/lantern/
Frédéric Laurent http://www.opikanoba.org
--
Devenez redacteur <XML>fr et contribuez au developpement du
xml francophone (http://xmlfr.org/infos/redacteurs/) !
Liste de diffusion "xml-tech@xmlfr.org" (http://xmlfr.org).
Cette liste est a votre disposition pour discuter en francais de
tout sujet technique lie a XML.
Pour resilier votre abonnement, envoyez un message contenant
la commande "unsubscribe" a xml-tech-request@xmlfr.org
(mailto:xml-tech-request@xmlfr.org?Subject=unsubscribe)
Archive générée par hypermail 2.1.3 le 28/06/2004 - 11:06 UTC
webmaster@xmlfr.org
|