Opérations ensemblistes
Le langage XPath (XML Path) prend en charge l'opération ensembliste |
.
Opérateur d'union (|)
L'opérateur |
, ou opérateur d'union, retourne l'union de ses deux opérandes, lesquels doivent être des collections de nœuds. Par exemple, //author | //publisher
retourne une collection de nœuds qui combine tous les nœuds //author
et tous les nœuds //publisher
. Plusieurs opérateurs d'union peuvent être enchaînés pour combiner plusieurs collections de nœuds. Par exemple, //author | //publisher | //editor | //book-seller
retourne une collection de nœuds contenant tous les éléments //author
, //publisher
, //editor
et //book-seller elements
. L'opérateur d'union conserve l'ordre des documents et ne retourne pas de doublons.
Exemples
Expression | Référence |
---|---|
|
Collection de nœuds contenant les éléments |
|
Collection de nœuds contenant les éléments |
|
Collection de nœuds contenant tous les éléments |
|
Collection de nœuds contenant tous les éléments |
Exemple
L'exemple suivant illustre l'effet de l'opérateur d'union.
Fichier XML (test.xml)
<?xml version="1.0"?>
<test>
<x a="1">
<x a="2" b="B">
<x>
<y>y31</y>
<y>y32</y>
</x>
</x>
</x>
</test>
Fichier XSLT (test.xsl)
La feuille de style XSLT suivante sélectionne tous les éléments <x>
dont l'attribut a
est égal à 2
, plus les éléments <x>
qui n'ont pas d'attributs.
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<!-- Suppress text nodes not covered in subsequent template rule. -->
<xsl:template match="text()"/>
<!-- Handles a generic element node. -->
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:apply-templates select="*|@*" />
<xsl:if test="text()">
<xsl:value-of select="."/>
</xsl:if>
</xsl:element>
</xsl:template>
<!-- Handles a generic attribute node. -->
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="/test">
<xsl:apply-templates select="//x[@a=2] | //x[not(@*)]"/>
</xsl:template>
</xsl:stylesheet>
La transformation produit le résultat suivant :
<x a="2" b="B">
<x>
<y>31</y>
<y>y32</y>
</x>
</x>
<x>
<y>y31</y>
<y>y32</y>
</x>
Priorité
Le tableau suivant indique l'ordre des priorités (de la plus haute à la plus faible priorité) entre les opérateurs booléens et les opérateurs de comparaison.
Priorité | Opérateurs | Description |
---|---|---|
1 |
|
Regroupement |
2 |
|
Filtres |
3 |
|
Opérations de chemin |
4 |
|
Comparaisons |
5 |
|
Comparaisons |
6 |
|
Union |
7 |
|
Opérateur booléen NOT |
8 |
|
Opérateur booléen AND |
9 |
|
Opérateur booléen OR |
Exemple
L'exemple suivant illustre l'effet de la priorité des opérateurs présentée ci-dessus.
Fichier XML (test.xml)
<?xml version="1.0"?>
<test>
<x a="1">
<x a="2" b="B">
<x>
<y>y31</y>
<y>y32</y>
</x>
</x>
</x>
<x a="1">
<x a="2">
<y>y21</y>
<y>y22</y>
</x>
</x>
<x a="1">
<y>y11</y>
<y>y12</y>
</x>
<x>
<y>y03</y>
<y>y04</y>
</x>
</test>
Fichier XSLT de base (test.xsl)
Nous allons utiliser ce fichier XSLT de base comme point de départ pour la série d'illustrations qui suivent.
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<!-- Suppress text nodes not covered in subsequent template rule. -->
<xsl:template match="text()"/>
<!-- Handles a generic element node. -->
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:apply-templates select="*|@*" />
<xsl:if test="text()">
<xsl:value-of select="."/>
</xsl:if>
</xsl:element>
</xsl:template>
<!-- Handles a generic attribute node. -->
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Cas 0. Exécution du test
Vous pouvez ajouter la règle de modèle suivante à la feuille de style XSLT.
<xsl:template match="/test">
<xsl:apply-templates select="*|@*/>
</xsl:template>
Cela produira un document XML identique à celui d'origine, sans l'instruction de traitement <?xml version="1.0"?>
.
Les cas suivants présentent différentes façons d'écrire cette règle de modèle. Le but est d'indiquer l'ordre dans lequel les opérateurs XPath se lient à un élément.
Cas 1 : () produit une liaison plus forte que []
La règle de modèle suivante sélectionne le premier élément <y>
dans l'ordre des documents, parmi tous les éléments <y>
du document source.
<xsl:template match="/test">
<xsl:apply-templates select="(//y)[1]"/>
</xsl:template>
Le résultat est le suivant :
<y>y31</y>
Cas 2 : [] produit une liaison plus forte que / ou //
La règle de modèle suivante sélectionne tous les éléments <y>
qui sont les premiers parmi leurs frères.
<xsl:template match="/test">
<xsl:apply-templates select="//y[1]"/>
</xsl:template>
Le résultat est le suivant :
<y>y31</y>
<y>y21</y>
<y>y11</y>
<y>y03</y>
Cas 3 : and, not
La règle de modèle suivante sélectionne tous les éléments <x>
qui n'ont pas d'éléments <x>
enfants, qui ont un élément <x>
parent et qui n'ont pas d'attributs.
<xsl:template match="/test">
<xsl:apply-templates select=
"//x[./ancestor::*[name()='x'] and *[name()!='x'] and not(@*)]"/>
</xsl:template>
Le résultat est un seul élément <x>
, présenté ci-dessous avec ses enfants :
<x>
<y>y31</y>
<y>y32</y>
</x>
Cas 4 : or, and, not
La règle de modèle suivante sélectionne chaque élément <x>
qui est un enfant d'un élément <x>
ou qui n'est pas un parent d'un élément <x>
et n'a pas d'attributs.
<xsl:template match="/test">
<xsl:apply-templates select=
"//x[./ancestor::*[name()='x'] or *[name()!='x'] and not(@*)]"/>
</xsl:template>
Le résultat est une collection de nœuds contenant les éléments <x>
suivants, présentée ci-dessous avec ses enfants :
<x a="2" b="B">
<x>
<y>y31</y>
<y>y32</y>
</x>
</x>
<x>
<y>y31</y>
<y>y32</y>
</x>
<x a="2">
<y>y21</y>
<y>y22</y>
</x>
<x>
<y>y03</y>
<y>y04</y>
</x>
Cas 5 : and, or, not
La règle de modèle suivante sélectionne chaque élément <x>
qui est un enfant d'un élément <x>
, mais qui n'est pas un parent d'un élément <x>
ou qui n'a pas d'attributs.
<xsl:template match="/test">
<xsl:apply-templates select=
"//x[./ancestor::*[name()='x'] and *[name()!='x'] or not(@*)]"/>
</xsl:template>
Le résultat est une collection de nœuds contenant les éléments <x>
suivants, présentée ci-dessous avec ses enfants :
<x>
<y>y31</y>
<y>y32</y>
</x>
<x a="2">
<y>y21</y>
<y>y22</y>
</x>
<x>
<y>y03</y>
<y>y04</y>
</x>