osdir.com
mailing list archive
Mozy Online Backup: 2GB Free. Automatic. Secure.

Subject: Re: récupérer tous les enfants(directs ou "indirects") de premiers niveau ? - msg#00108

List: text.xml.french.tech

Date: Prev Next Index Thread: Prev Next Index
pas très élégant... à vrai dire je n'en doute pas, je n'ai pas eu de
formation à xsl ni vraiment en informatique pour tout dire...
J'apprend xsl au fur et à mesure des besoins que je rencontre et c'est
sûrement dommage car je dois me compliquer la vie des fois ;)
C'est aussi souvent un problème de temps, il faut développer vite mais c'est
vrai, parfois perdre un peu de temps à court terme en fait gagner beaucoup à
long terme !
C'est ici l'occasion d'apprendre justement...

Je crois n'avoir pas ou mal compris la solution de stéphane. Je ne sais pas
trop où insérer le traitement (="afficher A + son id")
Je travail en output=html, et en faisant tourner cette xsl je récupère tous
les noeuds A.
Comme je l'avais écrit j'ai l'impression que cette solution me permet de
récupérer l'arbre xml des A (non ?). N'est-ce pas le but des <xsl:copy> ?
Ta solution Eric ne va-t-elle pas dans le même sens en récupérant la
hiérarchie des A dans <resultat> ?
d'autre part dans mon cas réél je n'ai pas d'@id comme énoncé dans le 1er
message, je les ai mis juste histoire de mieux comprendre et pouvoir écrire
le résulat A1, A2, A3... plus explicitement.

Si je reprend la solution d'Eric en output=html cela donne-t-il ? :
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:output method="html"/>

<xsl:template match="root|A">
<xsl:value-of select="@id"/>
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="*">
<xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

Je récupère tous les neouds A ici, ce que j'aimerai c'est pour chaque noeud
A, matcher chacun des sous-noeud A (direct ou indirecte mais 1seul niveau de
A).

Disons qu'en sortie HTML j'aimerai pouvoir écrire :

à partir du même fichier xml :
<root>
<A id="context">
<foo>
<A id="1">
<A id="1.1"/>
<bar>
<A id="1.2"/>
</bar>
</A>
</foo>
<A id="2"/>
<fred>
<waldo>
<A id="3">
<A id="3.1"/>
</A>
</waldo>
</fred>
</A>
</root>

SORTIE :
Acontext:
==> A1
==> A2
==> A3

A1 :
==> A1.1
==> A1.2

A2 :

A3 :
==> A3.1

A1.1 :

A1.2 :

A3.1 :

Je n'arrive pas à obtenir ce résultat à partir des solutions proposées,
avec le template reccursif j'y arrive facilement :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:template match="root">
Résultat : <br/>
<xsl:for-each select="A | //A">
A<xsl:value-of select="@id"/> : <br/>
<xsl:for-each select="*">
<xsl:call-template name="MatchA1erNiveau"/>
</xsl:for-each>
<br/>
</xsl:for-each>
</xsl:template>

<xsl:template name="MatchA1erNiveau">
<xsl:choose>
<xsl:when test="name()='A'">
==> A<xsl:value-of select="@id"/><br/>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="*">
<xsl:call-template
name="MatchA1erNiveau"/>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

Ou peut être (un peu) mieux ? :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:template match="root">
Résultat : <br/>
<xsl:apply-templates select="A | //A"/>
</xsl:template>
<xsl:template match="A">
A<xsl:value-of select="@id"/> : <br/>
<xsl:for-each select="*">
<xsl:call-template name="MatchA1erNiveau"/>
</xsl:for-each>
<br/>
</xsl:template>
<xsl:template name="MatchA1erNiveau">
<xsl:choose>
<xsl:when test="name()='A'">
==> A<xsl:value-of select="@id"/><br/>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="*">
<xsl:call-template
name="MatchA1erNiveau"/>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

Je crois qu'il y a quelquechose que je n'ai pas compris dans vos solutions,
ou alors mon problème n'était pas assez clairement posé, je ne sais pas...
sincèrement.

je pense que la sortie proposée ici ne peut que répondre parfaitement à mon
problème réél, aussi je suis preneur d'une xsl plus élégante qui donne la
même sortie.
Encore une fois désolé si j'ai du mal à comprendre, je ne suis pas habitué à
cette utilisation très déclarative d'xsl.

Matthieu.


-----Message d'origine-----
De : xml-tech-bounce@xxxxxxxxx [mailto:xml-tech-bounce@xxxxxxxxx]De la
part de Eric van der Vlist
Envoyé : vendredi 23 septembre 2005 13:43
À : xml-tech@xxxxxxxxx
Objet : [xml-tech] Re: récupérer tous les enfants(directs ou
"indirects") de premiers niveau ?


Le vendredi 23 septembre 2005 à 13:33 +0200, Matthieu Ricaud a écrit :
> C'est bon, le template récursif était super simple en fait... :
> <xsl:template match="root">
> <xsl:for-each select="A">
> <xsl:for-each select="*">
> <xsl:call-template name="MatchA1erNiveau"/>
> </xsl:for-each>
> </xsl:for-each>
> </xsl:template>
>
> <xsl:template name="MatchA1erNiveau">
> <xsl:choose>
> <xsl:when test="name()='A'">
> A<xsl:value-of select="@id"/>
> </xsl:when>
> <xsl:otherwise>
> <xsl:for-each select="*">
> <xsl:call-template
> name="MatchA1erNiveau"/>
> </xsl:for-each>
> </xsl:otherwise>
> </xsl:choose>
> </xsl:template>

Cela marche, mais vous ne tirez pas partie du caractère déclaratif de
XML avec vos xsl:for-each, xsl:call-template et xsl:choose...

Ce que vous faites est en somme l'équivalent non déclaratif (donc moins
élégant en XSLT) de ce qu'avait proposé Stéphane Bonhomme :

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root|A">
<xsl:copy>
<xsl:copy-of select="@id"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

Si vous voulez "isoler" ces traitements, il suffit d'utiliser un mode :

xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<xsl:copy>
<xsl:copy-of select="@id"/>
<xsl:apply-templates mode="filtrage"/>
</xsl:copy>
</xsl:template>
<xsl:template match="A" mode="filtrage">
<xsl:copy>
<xsl:copy-of select="@id"/>
<xsl:apply-templates mode="filtrage"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="filtrage">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

Quant à la dernière transformation que je vous ai proposée :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:template match="/">
<resultat>
<xsl:apply-templates select="//A[not(ancestor::A)]"/>
</resultat>
</xsl:template>
<xsl:template match="A">
<xsl:copy>
<!-- insérer votre traitement à la place de l'instruction
suivante -->
<xsl:copy-of select="@*"/>
<!--<xsl:apply-templates select=".//A[ count(ancestor::A) =
count(current()/ancestor-or-self::A) ]"/>-->
<!--<xsl:apply-templates select=".//A[ count(ancestor::A[1] |
current() ) = 1 ]"/>-->
<xsl:apply-templates select=".//A[generate-id(ancestor::A[1]) =
generate-id(current())]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Elle est équivalente si ce n'est que le filtrage des noeuds est fait
dans les "select" au lieu d'être fait dans les "match".

Suivant les cas, l'un ou l'autre peut être préférable... Dans votre cas,
le filtrage au niveau des match est plus simple et il semble convenir
(ceci dit, cela dépend du traitement que vous voulez insérer, si par
exemple vous aviez besoin de compter le nombre des noeuds de niveau
inférieur, l'expression XPath redeviendrait bien utile).

Cordialement,

Eric van der Vlist


--
Have you ever thought about unit testing XSLT templates?
http://xsltunit.org
------------------------------------------------------------------------
Eric van der Vlist http://xmlfr.org http://dyomedea.com
(ISO) RELAX NG ISBN:0-596-00421-4 http://oreilly.com/catalog/relax
(W3C) XML Schema ISBN:0-596-00252-1 http://oreilly.com/catalog/xmlschema
------------------------------------------------------------------------


--
Devenez redacteur <XML>fr et contribuez au developpement du
xml francophone (http://xmlfr.org/infos/redacteurs/) !

Liste de diffusion "xml-tech@xxxxxxxxx" (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@xxxxxxxxx
(mailto:xml-tech-request@xxxxxxxxx?Subject=unsubscribe)




Was this page helpful?
Yes No
Thread at a glance:

Previous Message by Date: click to view message preview

Re: récupérer tous les enfants (directs ou "indirects") de premiers niveau ?

Bonjour, je pense que plusieurs choses sont inutiles ici <xsl:template match="root"> <!--le template va passer tous les A de premier niveau--> <xsl:call-template name="MatchA1erNiveau"/> </xsl:template> <xsl:template name="MatchA1erNiveau" match="A"> A<xsl:value-of select="@id"/> <!--on re appelle le template pour les enfants <xsl:apply-templates/> </xsl:template> Sébastien TISCAR ASTASIO Sofréavia Tel : +(33 0) 1-41-23-46-74 Cel : +(33 0) 6-99-16-65-11 e-mail: tiscars@xxxxxxxxxxxx http://www.sofreavia.com ----- Original Message ----- From: "Matthieu Ricaud" <matthieu.ricaud@xxxxxxx> To: <xml-tech@xxxxxxxxx> Sent: Friday, September 23, 2005 12:33 PM Subject: [xml-tech] Re: récupérer tous les enfants (directs ou "indirects") de premiers niveau ? C'est bon, le template récursif était super simple en fait... : <xsl:template match="root"> <xsl:for-each select="A"> <xsl:for-each select="*"> <xsl:call-template name="MatchA1erNiveau"/> </xsl:for-each> </xsl:for-each> </xsl:template> <xsl:template name="MatchA1erNiveau"> <xsl:choose> <xsl:when test="name()='A'"> A<xsl:value-of select="@id"/> </xsl:when> <xsl:otherwise> <xsl:for-each select="*"> <xsl:call-template name="MatchA1erNiveau"/> </xsl:for-each> </xsl:otherwise> </xsl:choose> </xsl:template> Je descend d'un niveau à chaque fois que le fils direct n'est pas un A et ce jusqu'à ce que je trouve un A ou qu'il n'y a plus d'enfants... Un peu de copié/coller dans ma xsl et tout devrait rentrer dans l'ordre. Désolé de ne pas avoir été très pertinent dans mon exemple, je m'en suis rendu compte au fur et à mesure. On veut simplifier et on finit par trop le faire... Merci à tous en tout cas de vos réactions ! Matt -----Message d'origine----- De : xml-tech-bounce@xxxxxxxxx [mailto:xml-tech-bounce@xxxxxxxxx]De la part de Matthieu Ricaud Envoyé : vendredi 23 septembre 2005 13:19 À : xml-tech@xxxxxxxxx Objet : [xml-tech] Re: récupérer tous les enfants (directs ou "indirects") de premiers niveau ? Merci Erwan, c'est plus clair maintenant. "Pour que cela marche il faut bien sur être positionne sur un noeud qui est l'ancetre de tous les noeuds A"... oui en effet dans ce cas ce serait plus simple... Mais malheureusement ce n'est pas mon cas ! Je veux pouvoir me placer sur n'importe quel noeud A et matcher avec un select ses fils A (ou sous-fils si jamais un foo, ou un bar ou plusieurs se sont intercallés entre les deux...) Eric je viens de lire ta réponse, merci de ta patience et ta pédagogie. Je me rend compte que mon exemple était trop implicite, j'aurai dû préciser que mon template devait pouvoir fonctionner sur n'importe quel noeud A et permettre de matcher sa sous arborescence A de 1er niveau. en espérant avoir bien interprété vos explications... je crois que je vais devoir passer par un template récursif, à moins qu'il y ait un autre prédicat magique qui fasse cela ? Je vais tester le récursif pour voir. Je vous tiens au courant. -----Message d'origine----- De : xml-tech-bounce@xxxxxxxxx [mailto:xml-tech-bounce@xxxxxxxxx]De la part de Amoureux erwan Envoyé : vendredi 23 septembre 2005 12:48 À : xml-tech@xxxxxxxxx Objet : [xml-tech] Re: récupérer tous les enfants (directs ou "indirects") de premiers niveau ? En français la formule file://A[ count(ancestor::A) = count(current()/A/ancestor-or-self::A)] signifie : "les sous-noeuds A (de n'importe quel niveau) dont le nombre de parents A est égale au nombre de parent (lui y compris) qu'a son fils A" ??? je ne saisie pas bien (du tout!) ce prédicat... donc dur de l'adapter ! Tel quel: Tous les noeuds A qui ont le meme nombre d'ancetre A que le noeud courant +1(Le +1 est obtenu grace au self, il se compte lui meme) Pour que cela marche il faut bien sur être positionne sur un noeud qui est l'ancetre de tous les noeuds A -- Devenez redacteur <XML>fr et contribuez au developpement du xml francophone (http://xmlfr.org/infos/redacteurs/) ! Liste de diffusion "xml-tech@xxxxxxxxx" (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@xxxxxxxxx (mailto:xml-tech-request@xxxxxxxxx?Subject=unsubscribe) -- Devenez redacteur <XML>fr et contribuez au developpement du xml francophone (http://xmlfr.org/infos/redacteurs/) ! Liste de diffusion "xml-tech@xxxxxxxxx" (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@xxxxxxxxx (mailto:xml-tech-request@xxxxxxxxx?Subject=unsubscribe) -- Devenez redacteur <XML>fr et contribuez au developpement du xml francophone (http://xmlfr.org/infos/redacteurs/) ! Liste de diffusion "xml-tech@xxxxxxxxx" (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@xxxxxxxxx (mailto:xml-tech-request@xxxxxxxxx?Subject=unsubscribe)

Next Message by Date: click to view message preview

Re: récupérer tous les enfants(directs ou "indirects") de premiers niveau ?

Le vendredi 23 septembre 2005 à 17:06 +0200, Matthieu Ricaud a écrit : .../... > > SORTIE : > Acontext: > ==> A1 > ==> A2 > ==> A3 > > A1 : > ==> A1.1 > ==> A1.2 > > A2 : > > A3 : > ==> A3.1 > > A1.1 : > > A1.2 : > > A3.1 : > > Je n'arrive pas à obtenir ce résultat à partir des solutions proposées, Il y a d'autres manières de procéder, mais j'obtiens ce résultat avec la transformation suivante (qui est 100% déclarative) : <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="root"> <xsl:text>Résultat : </xsl:text> <xsl:apply-templates select="//A" mode="tous"/> </xsl:template> <xsl:template match="A" mode="tous"> <xsl:text>&#xa; &#xa; A</xsl:text> <xsl:value-of select="@id"/> <xsl:text> : </xsl:text> <xsl:apply-templates select="*" mode="fils"/> </xsl:template> <xsl:template match="*" mode="fils"> <xsl:apply-templates select="*" mode="fils"/> </xsl:template> <xsl:template match="A" mode="fils"> <xsl:text>&#xa; ==> A</xsl:text> <xsl:value-of select="@id"/> </xsl:template> </xsl:stylesheet> J'ai utilisé des modes pour différencier les traitements à effectuer pour créer une liste générale (mode "tous") et trouver les enfants logiques directs (mode "fils"). Cordialement, Eric van der Vlist -- If you have a XML document, you have its schema. http://examplotron.org ------------------------------------------------------------------------ Eric van der Vlist http://xmlfr.org http://dyomedea.com (ISO) RELAX NG ISBN:0-596-00421-4 http://oreilly.com/catalog/relax (W3C) XML Schema ISBN:0-596-00252-1 http://oreilly.com/catalog/xmlschema ------------------------------------------------------------------------

Previous Message by Thread: click to view message preview

Re: récupérer tous les enfants (directs ou "indirects") de premiers niveau ?

Le vendredi 23 septembre 2005 à 13:33 +0200, Matthieu Ricaud a écrit : > C'est bon, le template récursif était super simple en fait... : > <xsl:template match="root"> > <xsl:for-each select="A"> > <xsl:for-each select="*"> > <xsl:call-template name="MatchA1erNiveau"/> > </xsl:for-each> > </xsl:for-each> > </xsl:template> > > <xsl:template name="MatchA1erNiveau"> > <xsl:choose> > <xsl:when test="name()='A'"> > A<xsl:value-of select="@id"/> > </xsl:when> > <xsl:otherwise> > <xsl:for-each select="*"> > <xsl:call-template > name="MatchA1erNiveau"/> > </xsl:for-each> > </xsl:otherwise> > </xsl:choose> > </xsl:template> Cela marche, mais vous ne tirez pas partie du caractère déclaratif de XML avec vos xsl:for-each, xsl:call-template et xsl:choose... Ce que vous faites est en somme l'équivalent non déclaratif (donc moins élégant en XSLT) de ce qu'avait proposé Stéphane Bonhomme : <xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match="root|A"> <xsl:copy> <xsl:copy-of select="@id"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="*"> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet> Si vous voulez "isoler" ces traitements, il suffit d'utiliser un mode : xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match="root"> <xsl:copy> <xsl:copy-of select="@id"/> <xsl:apply-templates mode="filtrage"/> </xsl:copy> </xsl:template> <xsl:template match="A" mode="filtrage"> <xsl:copy> <xsl:copy-of select="@id"/> <xsl:apply-templates mode="filtrage"/> </xsl:copy> </xsl:template> <xsl:template match="*" mode="filtrage"> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet> Quant à la dernière transformation que je vous ai proposée : <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <resultat> <xsl:apply-templates select="//A[not(ancestor::A)]"/> </resultat> </xsl:template> <xsl:template match="A"> <xsl:copy> <!-- insérer votre traitement à la place de l'instruction suivante --> <xsl:copy-of select="@*"/> <!--<xsl:apply-templates select=".//A[ count(ancestor::A) = count(current()/ancestor-or-self::A) ]"/>--> <!--<xsl:apply-templates select=".//A[ count(ancestor::A[1] | current() ) = 1 ]"/>--> <xsl:apply-templates select=".//A[generate-id(ancestor::A[1]) = generate-id(current())]"/> </xsl:copy> </xsl:template> </xsl:stylesheet> Elle est équivalente si ce n'est que le filtrage des noeuds est fait dans les "select" au lieu d'être fait dans les "match". Suivant les cas, l'un ou l'autre peut être préférable... Dans votre cas, le filtrage au niveau des match est plus simple et il semble convenir (ceci dit, cela dépend du traitement que vous voulez insérer, si par exemple vous aviez besoin de compter le nombre des noeuds de niveau inférieur, l'expression XPath redeviendrait bien utile). Cordialement, Eric van der Vlist -- Have you ever thought about unit testing XSLT templates? http://xsltunit.org ------------------------------------------------------------------------ Eric van der Vlist http://xmlfr.org http://dyomedea.com (ISO) RELAX NG ISBN:0-596-00421-4 http://oreilly.com/catalog/relax (W3C) XML Schema ISBN:0-596-00252-1 http://oreilly.com/catalog/xmlschema ------------------------------------------------------------------------

Next Message by Thread: click to view message preview

Re: récupérer tous les enfants(directs ou "indirects") de premiers niveau ?

Le vendredi 23 septembre 2005 à 17:06 +0200, Matthieu Ricaud a écrit : .../... > > SORTIE : > Acontext: > ==> A1 > ==> A2 > ==> A3 > > A1 : > ==> A1.1 > ==> A1.2 > > A2 : > > A3 : > ==> A3.1 > > A1.1 : > > A1.2 : > > A3.1 : > > Je n'arrive pas à obtenir ce résultat à partir des solutions proposées, Il y a d'autres manières de procéder, mais j'obtiens ce résultat avec la transformation suivante (qui est 100% déclarative) : <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="root"> <xsl:text>Résultat : </xsl:text> <xsl:apply-templates select="//A" mode="tous"/> </xsl:template> <xsl:template match="A" mode="tous"> <xsl:text>&#xa; &#xa; A</xsl:text> <xsl:value-of select="@id"/> <xsl:text> : </xsl:text> <xsl:apply-templates select="*" mode="fils"/> </xsl:template> <xsl:template match="*" mode="fils"> <xsl:apply-templates select="*" mode="fils"/> </xsl:template> <xsl:template match="A" mode="fils"> <xsl:text>&#xa; ==> A</xsl:text> <xsl:value-of select="@id"/> </xsl:template> </xsl:stylesheet> J'ai utilisé des modes pour différencier les traitements à effectuer pour créer une liste générale (mode "tous") et trouver les enfants logiques directs (mode "fils"). Cordialement, Eric van der Vlist -- If you have a XML document, you have its schema. http://examplotron.org ------------------------------------------------------------------------ Eric van der Vlist http://xmlfr.org http://dyomedea.com (ISO) RELAX NG ISBN:0-596-00421-4 http://oreilly.com/catalog/relax (W3C) XML Schema ISBN:0-596-00252-1 http://oreilly.com/catalog/xmlschema ------------------------------------------------------------------------
Sign up for updates to this mailing list. email:
Loading Comments...
Home | News | Patents | Sitemap | FAQ | advertise

Advertising by