Partager via


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

first-name | last-name

Collection de nœuds contenant les éléments <first-name> et <last-name> dans le contexte actuel.

(bookstore/book | bookstore/magazine)

Collection de nœuds contenant les éléments <book> ou <magazine> dans un élément <bookstore>.

book | book/author

Collection de nœuds contenant tous les éléments <book> et tous les éléments <author> dans des éléments <book>.

(book | magazine)/price

Collection de nœuds contenant tous les éléments <price> des éléments <book> ou <magazine>.

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

&lt;

&lt;=

&gt;

&gt;=

Comparaisons

5

=

!=

Comparaisons

6

|

Union

7

not()

Opérateur booléen NOT

8

and

Opérateur booléen AND

9

or

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>