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)
>
>