Accueil
 chercher             Plan du site             Info (English version) 
L'histoire de XML s'écrit en ce moment même. XMLfr vous aide à la suivre et à en dégager les tendances.Les listes de discussions XMLfr sont à votre disposition pour réagir sur nos articles ou simplement poser une question.Si vous ètes passionnée(e) par XML, pourquoi ne pas en faire votre métier ?XMLfr n'est heureusement pas le seul site où l'on parle de XML. Découvrez les autres grâce à XMLfr et à l'ODP.Les partenaires grâce auxquels XMLfr peut se développer.Pour tout savoir sur XMLfr.XMLfr sans fil, c'est possible !Pour ceux qui veulent vraiment en savoir plus sur XML.L'index du site.
 Si vous vous posez une question, vous n'êtes peut-être pas le premier...Les traductions en français des bibles XML.Ces articles sont des références dans leur domaine.Tout ce qu'il faut savoir pour démarrer sur un sujet XML...


Expressions XPath utilisables dans l'attribut match de <xsl:template/>

J'ai une erreur lorsque j'utilise certaines expressions XPath dans l'attribut match de <xsl:template/>. Quelles restrictions s'appliquent à ces expressions?

Eric van der Vlist, Dyomedea (vdv@dyomedea.com).
jeudi 3 février 2005

Table des matières

Question

Réponse

Retour vers la recommandation

Mais encore?

Contournement

Et les variables?

Références

Question

J'ai une erreur lorsque j'utilise "following-sibling" dans l'attribut match de <xsl:template/>, par exemple :

<xsl:template match="following-sibling::noeud">

En revanche, si je met le "following-sibling" dans un "select=..", par exemple :

<xsl:apply-templates select="following-sibling::noeud"/>

ça fonctionne sans problème.Quelles restrictions s'appliquent à ces expressions?

Comment faire pour les contourner?

Réponse

Retour vers la recommandation

Les restrictions imposées aux expressions XPath dans l'attribut match d'un template sont définies par la recommandation XSLT 1.0 qui explique :

"Un motif doit concorder avec la grammaire des motifs (Pattern). Un motif est un ensemble de motifs de chemins de localisation séparés par |. Un motif de chemin de localisation est un chemin de localisation dont les étapes n'utilisent que les axes child ou attribute. Bien que les motifs ne doivent pas utiliser l'axe descendant-or-self, ils peuvent utiliser l'opérateur // tout aussi bien que l'opérateur /. Les motifs de chemins de localisation peuvent aussi commencer par un appel de fonction id ou key avec un argument littéral. Les prédicats d'un motif peuvent utiliser n'importe quelle expression exactement comme ceux des chemins de localisation."

Avant d'en donner la grammaire sous forme EBNF...

[1] Pattern ::= 
     LocationPathPattern | 
     Pattern '|'LocationPathPattern

[2] LocationPathPattern ::= 
    '/' RelativePathPattern? | 
    IdKeyPattern (('/' | '//') RelativePathPattern)? | 
    '//'? RelativePathPattern 

[3] IdKeyPattern ::=
    'id' '(' Literal ')' | 
    'key' '(' Literal ',' Literal ')' 

[4] RelativePathPattern ::=
    StepPattern | 
    RelativePathPattern '/' StepPattern | 
    RelativePathPattern '//' StepPattern 

[5] StepPattern ::=
    ChildOrAttributeAxisSpecifierNodeTestPredicate* 

[6] ChildOrAttributeAxisSpecifier ::=
    AbbreviatedAxisSpecifier | 
    ('child' | 'attribute') '::'

L'axe following-sibling est donc effectivement interdit.

Mais encore?

Le but des expressions XPath utilisées dans les attributs match est de qualifier des conditions portant sur des noeuds. C'est également l'objectif des prédicats XPath et lorsque l'on écrit :

<xsl:template match="foo/bar">

ce n'est qu'un raccourci pour sélectionner les éléments "bar" dont le parent est un élément "foo", autrement dit :

<xsl:template match="bar[parent::foo]"/>

Dans la mesure où il n'y a qu'une seule restriction sur les prédicats (les références à des variables sont interdites) les restrictions sur les expressions XPath utilisables dans les attributs match ne doivent donc pas être vues comme limitant le pouvoir expressif de ces expressions mais plutôt comme cherchant à éviter des expressions qui deviendraient rapidement illisibles.

Contournement

Pour contourner ces restrictions, il suffit d'utiliser des prédicats XPath.

L'exemple qui nous a été donné :

<xsl:template match="following-sibling::noeud">

n'est pas valide et ne peut donc pas être interprété seul, mais l'intention était ici de sélectionner les noeuds frères suivant un élément 'noeud'.

Le prédicat équivalent est donc :

<xsl:template match="node()[preceding-sibling::noeud]">

Ce qui signifie "les noeuds précédés par un frère ayant pour nom 'noeud' ".

Si ne nous intéressons qu'aux noeuds éléments, cela peut être simplifié en :

<xsl:template match="*[preceding-sibling::noeud]">

Et les variables?

La restriction concernant les variables ne peut pas être contournée directement. La recommandation est particulièrement claire à ce sujet puisqu'elle dit :

"Si la valeur de l'attribut match contient une expression de type VariableReference c'est une erreur. "

C'est donc une limitation au pouvoir déclaratif des templates XSLT et le seul contournement lorsque l'on aurait vraiment besoin d'utiliser une variable dans une clause match est d'avoir recours à une instruction xsl:if ou xsl:choose à l'intérieur d'un template.

Ainsi par exemple, si je veux supprimer d'un document tous les éléments dont le nom m'est passé dans le paramètre $aSupprimer, je n'aurai pas le droit d'écrire :

<xsl:template match="*[name()!=$aSupprimer]"/>

Et il faudra que je définisse un template plus générique, portant sur tous les éléments et que j'effectue un test à l'intérieur de ce template, par exemple :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0">
    <xsl:param name="aSupprimer">foo</xsl:param>
    <xsl:template match="@*|node()" name="recopie">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:if test="name()!=$aSupprimer">
            <xsl:call-template name="recopie"/>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Il est à noter que si certaines implémentations XSLT telles que libxslt acceptent l'utilisation de variables dans les clauses match, il est fortement déconseillé de s'appuyer sur ce comportement contraire à la recommandation et donc non portable.

Références

Copyright 2005, Eric van der Vlist


 

Mots clés.



L'histoire de XML s'écrit en ce moment même. XMLfr vous aide à la suivre et à en dégager les tendances.


Les documents publiés sur ce site le sont sous licence "Open Content"
Conception graphique
  l.henriot  

Conception, réalisation et hébergement
Questions ou commentaires
  redacteurs@xmlfr.org