Re: Clés et documents

[email protected] Tue, 23 Jan 2007 01:05:26 +0100
Newsgroups gmane.text.xml.french.tech
Message-ID <[email protected]>
Bonjour Stéphane,

Le 19 janv. 07 à 08:23, Stéphane Bonhomme a écrit :

> Salut Bob !
>
> Merci pour ta réponse; mais elle ne me satisfait pas pour deux  
> raisons :
>
> 1 - ça ne fonctionne pas : si l'on repasse dans le contexte du  
> document
> source, on a du coup plus accès aux données du documents "filtre",  
> et du
> coup à l'attribut @vp (a moins de le sauver lui aussi dans une  
> variable).

Oui, c'est lourd de sauvegarder à chaque fois les noeuds contextes  
dans des variables, mais c'est tout ce que j'ai trouvé.

>
> 2 - D'après ce que je lis dans la spec xslt 1 l'appel de key peut se
> faire dans m'importe quel contexte (en particulier quelque soit le
> document du noeud courant).

Pour moi, les noeuds retournés par key() appartiennent au document  
"contexte courant" ! du moins, c'est ce que j'ai retenu, par  
expérience et me semble-t-il de mes lectures (in french, car pour  
moi, c'est plus clair que l'anglais)

> Je pense que c'est meme un moyen de
> "sauvegarder" le contexte plus élégament qu'avec l'utilisation d'une
> variable.

Effectivement, si ton hypothèse se vérifie, ce serait pratique

>
> (Ceci dit il y a de multiples façons de se sortir de ce problème, mais
> ce point titille mon esprit, j'aimerais comprendre pourquoi !)

Dans ton exemple si le nombre de filtre/ok n'est pas très élevé,  
amha, il sera tout aussi efficace de faire qque chose du genre :

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

   <xsl:template match="a">
	<xsl:variable name="a_courant" select="."/>
     <xsl:for-each select="document('filtre.xml')/filtre/ok">
       <xsl:value-of select="concat(@vp, ' = ', $a_courant/ref[@p =  
current()/@vp]/@v)"/>;
     </xsl:for-each>
   </xsl:template>

</xsl:stylesheet>

J'ai fait il y a 2 ou 3 ans de nombreux tests de performance avec des  
key(), selon le processeur xslt utilisé, les résultats sont très  
variables en terme de de performance :-( celui qui s'en sortait le  
mieux (et de loin) à l'époque était Saxon.

J'essaierai de me replonger dans les spéc et dans mes bouquins qui  
tratitent de l'utilisation des key()

a+
bonne journée

bob


>
> Steph.
>
> [email protected] wrote:
>
>> Bonsoir Stéphane,
>> Le 18 janv. 07 à 19:32, Stéphane Bonhomme a écrit :
>>
>>
>>
>>> Bonjour;
>>>
>>> J'ai une petite question concernant les clés xslt 1.0 et le  
>>> traitement
>>> multi-documents :
>>>
>>> Dans un traitement utilisant la fonction document(), on peut  
>>> utiliser
>>> les clés pour adresser des noeuds d'un autre document (par  
>>> exemple le
>>> doc source de la transformation) : La spec xslt 1 (section 12.2) dit
>>> explicitement :
>>>
>>> "The *key <http://www.w3.org/TR/xslt#function-key>* can be used to
>>> retrieve a key from a document other than the document containing  
>>> the
>>> context node. For example, suppose a document contains bibliographic
>>> references in the form |<bibref>XSLT</bibref>|, and there is a
>>> separate
>>> XML document |bib.xml| containing a bibliographic database with
>>> entries
>>> in the form:"
>>> (suivi d'un exemple illustrant le concept)
>>>
>>> Pourtant, dans la pratique il semble qu'on ne peut pas utiliser les
>>> clés
>>> définies par xsl:key sur le document xsl source de la  
>>> transformation,
>>> j'ai testé avec plusieurs processeurs (libxslt, xalan et saxon) et
>>> tous
>>> ont le même comportement : il semble impossible d'adresser des clés
>>> définies sur un document quand le noeud courant appartient à un  
>>> autre
>>> document.
>>>
>>>
>>
>> Pour que ça fonctionne, l'appel de "key()" doit dans ce cas
>> s'effectuer dans le contexte de ton document source. Tu dois donc
>> sauvegarder le contexte "a" dans une variable.
>>
>> <?xml version="1.0" encoding="UTF-8" ?>
>> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
>> Transform">
>>
>>   <xsl:key match="/a/ref" name="cle" use="@p"/>
>>
>>   <xsl:template match="a">
>> 	<xsl:variable name="a_courant" select="."/>
>>     <xsl:for-each select="document('filtre.xml')/filtre/ok">
>>       <xsl:variable name="vp" select="@vp"/>
>>       <xsl:for-each select="$a_courant">
>>         <xsl:value-of select="$vp"/> = <xsl:value-of select="key
>> ('cle',$vp)/@v"/>;
>>       </xsl:for-each>
>>     </xsl:for-each>
>>   </xsl:template>
>>
>> </xsl:stylesheet>
>>
>> C'est un peu usine à gaz, Il doit y'avoir plus simple, mais si j'ai
>> pas fait de faute de frappe, ça doit marcher.
>>
>> Bob
>>
>> En guise de carte de voeux, une petite pub pour le nouveau projet du
>> photographe Yann Arthus-Bertrand
>> http://www.yannarthusbertrand.com/v2/Ecard/
>> http://www.yannarthusbertrand.com/
>>
>>
>>
>>
>>
>>> Voici un petit exemple qui illustre mon propos :
>>>
>>> fichier xml source :
>>> <a>
>>>  <ref p="1" v="A"/>
>>>  <ref p="2" v="B"/>
>>>  <ref p="3" v="C"/>
>>>  <ref p="4" v="D"/>
>>> </a>
>>>
>>> J'ai un fichier xml complémentaire qui permet de filtrer les  
>>> elements
>>> ref à afficher en fonction de la valeur de l'attribut p :
>>> filtre.xml :
>>> <filtre>
>>>  <ok vp="1"/>
>>>  <ok vp="3"/>
>>> </filtre>
>>>
>>> j'écrit un xsl qui m'affiche les couple de valeurs p=v pour les
>>> <ref> du
>>> doc source si et seulement si le filtre a un element ok abec un
>>> attribut
>>> vp égal a l'attribut p :
>>>
>>> <xsl:stylesheet version="1.0"
>>>  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
>>>
>>>  <xsl:key match="/a/ref" name="cle" use="@p"/>
>>>
>>>  <xsl:template match="a">
>>>    <xsl:for-each select="document('filtre.xml')/filtre/ok">
>>>      <xsl:value-of select="@vp"/> = <xsl:value-of
>>> select="key('cle',@vp)/@v"/>;
>>>    </xsl:for-each>
>>>  </xsl:template>
>>>
>>> </xsl:stylesheet>
>>>
>>> Je m'attends a avoir comme résultat :
>>> 1=A;
>>> 3=C;
>>>
>>> et pourtant j'obtiens :
>>> 1=;
>>> 3=;
>>>
>>> Qui se trompe ? les trois processeurs xslt, ou moi quand je lis la
>>> spec ?
>>>
>>> -- 
>>>   Stéphane Bonhomme           --           Exselt Services
>>>
>>> Formations, Conseil et Réalisations en Ingénierie Documentaire,
>>>            Technologies Web et Logiciels Libres
>>>     [email protected]   -   http://www.exselt.com
>>>        04 57 39 30 78        /      06 88 57 27 08
>>>
>>>
>>> --
>>> Devenez redacteur <XML>fr et contribuez au developpement du
>>> xml francophone (http://xmlfr.org/infos/redacteurs/) !
>>>
>>> Liste de diffusion "[email protected]" (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 [email protected]
>>> (mailto:[email protected]?Subject=unsubscribe)
>>>
>>>
>>>
>>>
>>
>>
>>
>> --
>> Devenez redacteur <XML>fr et contribuez au developpement du
>> xml francophone (http://xmlfr.org/infos/redacteurs/) !
>>
>> Liste de diffusion "[email protected]" (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 [email protected]
>> (mailto:[email protected]?Subject=unsubscribe)
>>
>>
>>
>
>
> -- 
>    Stéphane Bonhomme           --           Exselt Services
>
> Formations, Conseil et Réalisations en Ingénierie Documentaire,
>             Technologies Web et Logiciels Libres
>      [email protected]   -   http://www.exselt.com
>         04 57 39 30 78        /      06 88 57 27 08
>
>
> --
> Devenez redacteur <XML>fr et contribuez au developpement du
> xml francophone (http://xmlfr.org/infos/redacteurs/) !
>
> Liste de diffusion "[email protected]" (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 [email protected]
> (mailto:[email protected]?Subject=unsubscribe)
>
>