Discussion:
commande xsl dynamique pour le xml... au secours !!!
(trop ancien pour répondre)
nicopilami
2005-12-28 22:21:22 UTC
Permalink
Salut à tous, voilà mon probleme
j'ai créé dynamiquement une chaine de test, constituée de chaines de
caracteres concaténées;
la chaine commande est une chaine de caractees qui donne
"(@start='20051215083000 BST') and (@channel='TF1')"
jusque ici, tout va bien;

Maintenant, je souhaiterais (là est le pb) utiliser cette chaine comme
condition dans mon xsl:if; voilà le code que je voudrais utiliser... mais
qui ne marche pas...

<xsl:if test="$commande">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="category"/></td>
<td><xsl:value-of select="@channel"/></td>
<td><xsl:value-of select="@start"/></td>
</tr>
</xsl:if>

en effet, je pense que le parser xml/xsl ne reconnait pas la chaine
$commande comme une commande mais plutot comme une simple chaine de
caracteres... :'(

-> Pouvez-vous m'aider à résoudre mon probleme ?


merci d'avance
Nico
Florent Georges
2005-12-28 23:08:55 UTC
Permalink
Post by nicopilami
la chaine commande est une chaine de caractees qui donne
<xsl:if test="$commande">
La solution est de procéder en deux étapes. Tu crées d'abord un
script XSLT où tu insère la chaîne effectivement comme valeur de
l'attribut 'test', puis tu exécutes ce second script XSLT.

Selon la manière dont tu génère ta chaîne, tu peux peut-être
aussi éviter de la construire et imbriquer les 'if' en dur. Ou
utiliser un template récursif sur un node-set de noeuds représentant
les tests (ou sur une séquence, si tu utilises XSLT 2.0, auquel cas tu
peux utiliser un RTF pour les noeuds de test).

Sinon, il te reste toujours les extensions genre 'eval()'. Ou pour
échapper vers du Java, depuis une fonction XPath ou une instruction
XSLT.

Dis-en nous un peu plus sur la manière dont tu obtiens ta chaîne de
test.

--drkm
nicopilami
2005-12-29 00:08:11 UTC
Permalink
Post by Florent Georges
Dis-en nous un peu plus sur la manière dont tu obtiens ta chaîne de
test.
--------------------------------------------------------------------------------------------------------
voilà le code complet , ca sera plus explicite :
----------------------------------------------


<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="couleur"/>
<xsl:param name="date_demandee"/>
<xsl:param name="chaine_demandee"/>
<xsl:param name="categorie_demandee"/>

<xsl:template match="/">
<html>
<body>
<h2>Mon Programme TV</h2>
<table border="1">
<tr>
<xsl:attribute name="bgcolor"><xsl:value-of
select="$couleur"/></xsl:attribute>
<td>Programme</td>
<td>Categorie</td>
<td>Chaine</td>
<td>Heure</td>


</tr>
<!--xsl:variable name="chaine_test"
select="concat('(@start=',{$date_demandee},'')"-->
<xsl:variable name="texte_date">(@start='<xsl:value-of
select="$date_demandee"/>')</xsl:variable>

<xsl:variable name="texte_chaine">
<xsl:choose>
<xsl:when test="$chaine_demandee!=''">
and (@channel='<xsl:value-of select="$chaine_demandee"/>')
</xsl:when>
<xsl:otherwise>

</xsl:otherwise>
</xsl:choose>
</xsl:variable>

<xsl:variable name="texte_categorie">
<xsl:choose>
<xsl:when test="$categorie_demandee!=''">
and (category='<xsl:value-of select="$categorie_demandee"/>')
</xsl:when>
<xsl:otherwise>

</xsl:otherwise>
</xsl:choose>
</xsl:variable>

<xsl:variable name="chaine_commande">
<xsl:value-of
select="concat($texte_date,$texte_chaine,$texte_categorie)"></xsl:value-of>
</xsl:variable>



<xsl:value-of select="$chaine_commande"/>

<!--xsl:variable name="chaine_test">concat('2','3')</xsl:variable>
<xsl:variable name="zchaine_test">3</xsl:variable>

<xsl:value-of select="concat($texte_date,$texte_chaine)"></xsl:value-of>


<xsl:value-of select="concat('ttt',$zchaine_test)">tt</xsl:value-of>
<!-->

<xsl:for-each select="tv/programme">


<xsl:if test="$chaine_commande">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="category"/></td>
<td><xsl:value-of select="@channel"/></td>
<td><xsl:value-of select="@start"/></td>
</tr>
</xsl:if>

</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Florent Georges
2005-12-29 13:51:24 UTC
Permalink
Post by Florent Georges
Dis-en nous un peu plus sur la manière dont tu obtiens ta chaîne de
test.
C'est rarement une bonne idee. Il vaut mieux essayer d'obtenir un
exemple minimal et complet (ce qui avec XSLT veut dire "accompagne d'un
document d'entree).

Voici d'abord une version qui ne regle pas ton probleme, mais est une
retranscription presque automatique de ton script initial. Je te
laisse voir les differences et comprendre leur interet (s'il y a des
points obscurs, n'hesite pas).

<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="couleur"/>
<xsl:param name="date_demandee"/>
<xsl:param name="chaine_demandee"/>
<xsl:param name="categorie_demandee"/>

<xsl:template match="/">
<html>
<body>
<h2>Mon Programme TV</h2>
<table border="1">
<tr bgcolor="{$couleur}">
<td>Programme</td>
<td>Categorie</td>
<td>Chaine</td>
<td>Heure</td>
</tr>
<xsl:apply-templates select="tv/programme"/>
</table>
</body>
</html>
</xsl:template>

<xsl:template match="programme">
<xsl:variable name="chaine_commande">
<xsl:call-template name="get.test.string"/>
</xsl:variable>
<xsl:if test="string($chaine_commande)">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="category"/></td>
<td><xsl:value-of select="@channel"/></td>
<td><xsl:value-of select="@start"/></td>
</tr>
</xsl:if>
</xsl:template>

<xsl:template name="get.test.string">
(@start='<xsl:value-of select="$date_demandee"/>')
<xsl:if test="$chaine_demandee!=''">
and (@channel='<xsl:value-of select="$chaine_demandee"/>')
</xsl:if>
<xsl:if test="$categorie_demandee!=''">
and (category='<xsl:value-of select="$categorie_demandee"/>')
</xsl:if>
</xsl:template>

</xsl:stylesheet>

Voici maintenant une solution a ton probleme. D'apres ta
description, je pense qu'un test direct est suffisant et le plus
simple. Le factoriser dans un template nomme me semble a priori une
bonne idee.

<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>

<xsl:param name="couleur"/>
<xsl:param name="date_demandee"/>
<xsl:param name="chaine_demandee"/>
<xsl:param name="categorie_demandee"/>

<xsl:template match="/">
<html>
<body>
<h2>Mon Programme TV</h2>
<table border="1">
<tr bgcolor="{$couleur}">
<td>Programme</td>
<td>Categorie</td>
<td>Chaine</td>
<td>Heure</td>
</tr>
<xsl:apply-templates select="tv/programme"/>
</table>
</body>
</html>
</xsl:template>

<xsl:template match="programme">
<xsl:variable name="test.result">
<xsl:call-template name="perform.test"/>
</xsl:variable>
<xsl:if test="string($test.result)">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="category"/></td>
<td><xsl:value-of select="@channel"/></td>
<td><xsl:value-of select="@start"/></td>
</tr>
</xsl:if>
</xsl:template>

<xsl:template name="perform.test">
<xsl:param name="prog" select="."/>
<xsl:if test="$prog/@start=$date_demandee
and (not($chaine_demandee)
or $prog/@channel=$chaine_demandee)
and (not($categorie_demandee)
or $prog/category=$categorie_demandee)">
<xsl:value-of select="'true'"/>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

Teste avec l'entree suivante :

<tv>
<programme start="2005-12-29T14:30:00" channel="TF1">
<category>movie</category>
<title>Crap Movie</title>
</programme>
<programme start="2005-12-29T14:30:00" channel="RTBF">
<category>movie</category>
<title>Other movie</title>
</programme>
</tv>

Au fait, c'est quoi ce format de date que tu as utilise dans ton
article initial (20051215083000 BST) ?

--drkm
nicopilami
2005-12-29 14:28:11 UTC
Permalink
Post by Florent Georges
Au fait, c'est quoi ce format de date que tu as utilise dans ton
article initial (20051215083000 BST) ?
Ah !!! mon sauveur !!! ;o)
en effet ca marche bien et c'est vraiment plus clair !!!

le format de la date m'a été imposé :

2005annee 12mois 15jour 08h 30min 00sec BSTje sais pas ce que c'est

merci encore :)
bye
Nico
Florent Georges
2005-12-29 15:18:22 UTC
Permalink
Post by nicopilami
en effet ca marche bien et c'est vraiment plus clair !!!
Mais as-tu bien compris les differences ? La plus fondamentale en
regard de XSLT est l'utilisation d'un template rule (apply-templates +
template[@match]) sur les programmes.

L'utilisation d'un attribute value template (comme pour @bgcolor, en
employant des "{}") est importante egalement, elle permet souvent
d'avoir du code clair et est extremement simple a comprendre (tres
intuitive).
Post by nicopilami
2005annee 12mois 15jour 08h 30min 00sec BSTje sais pas ce que c'est
D'apres Google sur "bst date", il s'agit de "British Summer Time" :

http://wwp.greenwichmeantime.com/info/bst.htm
http://wwp.greenwichmeantime.com/info/bst2.htm

--drkm
Florent Georges
2005-12-29 15:21:33 UTC
Permalink
Post by nicopilami
2005annee 12mois 15jour 08h 30min 00sec BSTje sais pas ce que c'est
Au fait, je ne suis pas certain qu'utiliser une comparaison de chaine
soit le mieux adapte a ton probleme. Tu peux regarder du cote de EXSLT
pour des fonctions de gestion des datetimes ou du cote de XSLT/XPath
2.0, selon le processeur que tu utilises.

--drkm

Continuer la lecture sur narkive:
Loading...