"xml.etree.ElementTree" — L'API *ElementTree* XML
*************************************************

**Code Source:** Lib/xml/etree/ElementTree.py

======================================================================

Le  module "xml.etree.ElementTree" implémente une API simple et
efficace pour analyser et créer des données XML.

Modifié dans la version 3.3: ce module utilise une implémentation
rapide chaque fois que c'est possible.

Obsolète depuis la version 3.3: The "xml.etree.cElementTree" module is
deprecated.

Avertissement:

  le module "xml.sax" n'est pas sécurisé contre les données
  construites de façon malveillante. Si vous avez besoin d'analyser
  des données non sécurisées ou non authentifiées, référez-vous à
  Vulnérabilités XML.


Tutoriel
========

Ceci est un petit tutoriel pour utiliser "xml.etree.ElementTree"
("ET"). Le but est de montrer quelques composants et les concepts
basiques du module.


Arborescence et éléments XML
----------------------------

XML est un format de données fondamentalement hiérarchique et la façon
la plus naturelle de le représenter est avec un arbre. "ET" a deux
classes pour ce but : "ElementTree" représente l'ensemble du document
XML comme un arbre et "Element" représente un simple nœud dans cet
arbre. Les interactions (lire et écrire vers et depuis des fichiers)
sur le document sont habituellement effectuées au niveau de
"ElementTree". Les interactions sur un seul élément XML et ses sous-
éléments sont effectuées au niveau de "Element".


Analyse XML
-----------

We'll be using the fictive "country_data.xml" XML document as the
sample data for this section:

   <?xml version="1.0"?>
   <data>
       <country name="Liechtenstein">
           <rank>1</rank>
           <year>2008</year>
           <gdppc>141100</gdppc>
           <neighbor name="Austria" direction="E"/>
           <neighbor name="Switzerland" direction="W"/>
       </country>
       <country name="Singapore">
           <rank>4</rank>
           <year>2011</year>
           <gdppc>59900</gdppc>
           <neighbor name="Malaysia" direction="N"/>
       </country>
       <country name="Panama">
           <rank>68</rank>
           <year>2011</year>
           <gdppc>13600</gdppc>
           <neighbor name="Costa Rica" direction="W"/>
           <neighbor name="Colombia" direction="E"/>
       </country>
   </data>

Nous pouvons importer ces données en lisant un fichier :

   import xml.etree.ElementTree as ET
   tree = ET.parse('country_data.xml')
   root = tree.getroot()

Ou depuis une chaîne de caractères :

   root = ET.fromstring(country_data_as_string)

"fromstring()" analyse les données XML depuis une chaîne de caractères
et produit un "Element", qui est l'élément racine de l'arbre analysé.
D'autres fonctions d'analyse peuvent créer un "ElementTree".  Vérifiez
la documentation pour en être sûr.

En tant qu'"Element", "root" a une balise (*tag*) et un dictionnaire
d'attributs :

   >>> root.tag
   'data'
   >>> root.attrib
   {}

Il contient aussi des nœuds enfants sur lesquels nous pouvons itérer :

   >>> for child in root:
   ...     print(child.tag, child.attrib)
   ...
   country {'name': 'Liechtenstein'}
   country {'name': 'Singapore'}
   country {'name': 'Panama'}

Les enfants sont imbriqués et nous pouvons accéder aux nœuds enfants
spécifiques *via* un indice :

   >>> root[0][1].text
   '2008'

Note:

  les éléments du XML d'entrée ne sont pas tous considérés comme des
  éléments de l'arborescence. Actuellement, le module ignore les
  commentaires XML, les instructions de traitements et la déclaration
  du type de document dans l'entrée. Néanmoins, les arborescences
  construites en utilisant l'API du module plutôt que par l'analyse du
  texte XML peuvent contenir des commentaires et des instructions de
  traitement ; ils seront inclus lors de la génération du XML de
  sortie. La DTD du document est accessible en passant une instance de
  "TreeBuilder" au constructeur de "XMLParser".


API à flux tiré
---------------

La plupart des fonctions d'analyse fournies par ce module nécessitent
que le document entier soit lu en même temps avant de renvoyer un
résultat. Il est possible d'utiliser un "XMLParser" et d'y introduire
des données de manière incrémentielle, mais il s'agit d'une API à flux
poussé qui appelle des méthodes par rappel automatique, ce qui est de
trop bas niveau et peu pratique pour la plupart des besoins. Parfois,
ce que l'utilisateur souhaite réellement, c'est pouvoir analyser du
XML de manière incrémentielle, sans bloquer les opérations, tout en
bénéficiant de la commodité des objets "Element" entièrement
construits.

L'outil le plus puissant pour ce faire est "XMLPullParser". Il ne
nécessite pas de lecture bloquante pour obtenir les données XML et est
plutôt alimenté en données de manière incrémentielle avec des appels à
"XMLPullParser.feed()". Pour obtenir les éléments XML analysés,
appelez "XMLPullParser.read_events()". Voici un exemple :

   >>> parser = ET.XMLPullParser(['start', 'end'])
   >>> parser.feed('<mytag>sometext')
   >>> list(parser.read_events())
   [('start', <Element 'mytag' at 0x7fa66db2be58>)]
   >>> parser.feed(' more text</mytag>')
   >>> for event, elem in parser.read_events():
   ...     print(event)
   ...     print(elem.tag, 'text=', elem.text)
   ...
   end
   mytag text= sometext more text

Le cas d'utilisation évident concerne les applications qui
fonctionnent de manière non bloquante dans lesquelles les données XML
sont reçues à partir d'un connecteur réseau ou lues de manière
incrémentielle à partir d'un périphérique de stockage. Dans de tels
cas, le blocage des lectures est inacceptable.

Parce qu'il est très flexible, "XMLPullParser" peut être peu pratique
à utiliser pour des cas d'utilisation plus simples. Si cela ne vous
dérange pas que votre application se bloque pendant la lecture de
données XML mais que vous souhaitez tout de même disposer de capacités
d'analyse incrémentielle, jetez un œil à "iterparse()". Cela peut être
utile lorsque vous lisez un document XML volumineux et que vous ne
souhaitez pas le conserver entièrement en mémoire.

Where *immediate* feedback through events is wanted, calling method
"XMLPullParser.flush()" can help reduce delay; please make sure to
study the related security notes.


Atteinte d'éléments d'intérêt
-----------------------------

"Element" a quelques méthodes très utiles qui aident à parcourir
récursivement tous les sous-arbres (ses enfants, leurs enfants et
ainsi de suite). Par exemple, "Element.iter()" :

   >>> for neighbor in root.iter('neighbor'):
   ...     print(neighbor.attrib)
   ...
   {'name': 'Austria', 'direction': 'E'}
   {'name': 'Switzerland', 'direction': 'W'}
   {'name': 'Malaysia', 'direction': 'N'}
   {'name': 'Costa Rica', 'direction': 'W'}
   {'name': 'Colombia', 'direction': 'E'}

"Element.findall()" récupère seulement les éléments avec une balise
qui sont les descendants directs de l'élément courant.
"Element.find()" récupère le *premier* élément avec une balise
particulière et "Element.text" accède au contenu textuel de l'élément.
"Element.get()" accède aux attributs de l'élément :

   >>> for country in root.findall('country'):
   ...     rank = country.find('rank').text
   ...     name = country.get('name')
   ...     print(name, rank)
   ...
   Liechtenstein 1
   Singapore 4
   Panama 68

Une caractérisation plus sophistiquée des éléments à rechercher est
possible en utilisant XPath.


Modification d'un fichier XML
-----------------------------

"ElementTree" fournit un moyen simple de créer des documents XML et de
les écrire dans des fichiers. La méthode "ElementTree.write()" sert à
cet effet.

Une fois créé, un objet "Element" peut être manipulé en changeant
directement ses champs (tels que "Element.text"), en ajoutant et en
modifiant des attributs (méthode "Element.set()"), ou en ajoutant de
nouveaux enfants (par exemple avec "Element.append()").

Disons que nous voulons en ajouter un au classement de chaque pays, et
ajouter un attribut *updated* (« mis à jour ») à l'élément de
classement :

   >>> for rank in root.iter('rank'):
   ...     new_rank = int(rank.text) + 1
   ...     rank.text = str(new_rank)
   ...     rank.set('updated', 'yes')
   ...
   >>> tree.write('output.xml')

Maintenant, notre XML ressemble à ceci :

   <?xml version="1.0"?>
   <data>
       <country name="Liechtenstein">
           <rank updated="yes">2</rank>
           <year>2008</year>
           <gdppc>141100</gdppc>
           <neighbor name="Austria" direction="E"/>
           <neighbor name="Switzerland" direction="W"/>
       </country>
       <country name="Singapore">
           <rank updated="yes">5</rank>
           <year>2011</year>
           <gdppc>59900</gdppc>
           <neighbor name="Malaysia" direction="N"/>
       </country>
       <country name="Panama">
           <rank updated="yes">69</rank>
           <year>2011</year>
           <gdppc>13600</gdppc>
           <neighbor name="Costa Rica" direction="W"/>
           <neighbor name="Colombia" direction="E"/>
       </country>
   </data>

Nous pouvons supprimer des éléments en utilisant "Element.remove()".
Supposons que nous souhaitions supprimer tous les pays dont le
classement est supérieur à 50 :

   >>> for country in root.findall('country'):
   ...     # using root.findall() to avoid removal during traversal
   ...     rank = int(country.find('rank').text)
   ...     if rank > 50:
   ...         root.remove(country)
   ...
   >>> tree.write('output.xml')

Notez que les modifications simultanées lors de l'itération peuvent
entraîner des problèmes, tout comme lors de l'itération et de la
modification de listes ou de dictionnaires Python. Par conséquent,
l'exemple collecte d'abord tous les éléments correspondants avec
"root.findall()", et après seulement parcourt la liste des
correspondances.

Maintenant, notre XML ressemble à ceci :

   <?xml version="1.0"?>
   <data>
       <country name="Liechtenstein">
           <rank updated="yes">2</rank>
           <year>2008</year>
           <gdppc>141100</gdppc>
           <neighbor name="Austria" direction="E"/>
           <neighbor name="Switzerland" direction="W"/>
       </country>
       <country name="Singapore">
           <rank updated="yes">5</rank>
           <year>2011</year>
           <gdppc>59900</gdppc>
           <neighbor name="Malaysia" direction="N"/>
       </country>
   </data>


Création de documents XML
-------------------------

La fonction "SubElement()" fournit également un moyen pratique de
créer de nouveaux sous-éléments pour un élément donné :

   >>> a = ET.Element('a')
   >>> b = ET.SubElement(a, 'b')
   >>> c = ET.SubElement(a, 'c')
   >>> d = ET.SubElement(c, 'd')
   >>> ET.dump(a)
   <a><b /><c><d /></c></a>


Analyse d'un XML avec des espaces de noms
-----------------------------------------

Si l'entrée XML a des espaces de noms, les balises et les attributs
avec des préfixes sous la forme *préfixe:unebalise* sont étendus à
"{uri}unebalise" où le *préfixe* est remplacé par l'*URI* complet. De
plus, s'il existe un espace de noms par défaut, cet URI complet est
ajouté au début de toutes les balises non préfixées.

Voici un exemple XML qui intègre deux espaces de noms, l'un avec le
préfixe *fictional* et l'autre servant d'espace de noms par défaut :

   <?xml version="1.0"?>
   <actors xmlns:fictional="http://characters.example.com"
           xmlns="http://people.example.com">
       <actor>
           <name>John Cleese</name>
           <fictional:character>Lancelot</fictional:character>
           <fictional:character>Archie Leach</fictional:character>
       </actor>
       <actor>
           <name>Eric Idle</name>
           <fictional:character>Sir Robin</fictional:character>
           <fictional:character>Gunther</fictional:character>
           <fictional:character>Commander Clement</fictional:character>
       </actor>
   </actors>

Une façon de rechercher et d'explorer cet exemple XML consiste à
ajouter manuellement l'URI à chaque balise ou attribut dans le *xpath*
d'une recherche "find()" ou "findall()" :

   root = fromstring(xml_text)
   for actor in root.findall('{http://people.example.com}actor'):
       name = actor.find('{http://people.example.com}name')
       print(name.text)
       for char in actor.findall('{http://characters.example.com}character'):
           print(' |-->', char.text)

Une meilleure façon de rechercher dans l'exemple XML avec espace de
noms consiste à créer un dictionnaire avec vos propres préfixes et à
les utiliser dans les fonctions de recherche :

   ns = {'real_person': 'http://people.example.com',
         'role': 'http://characters.example.com'}

   for actor in root.findall('real_person:actor', ns):
       name = actor.find('real_person:name', ns)
       print(name.text)
       for char in actor.findall('role:character', ns):
           print(' |-->', char.text)

Ces deux approches donnent le même résultat :

   John Cleese
    |--> Lancelot
    |--> Archie Leach
   Eric Idle
    |--> Sir Robin
    |--> Gunther
    |--> Commander Clement


Prise en charge de *XPath*
==========================

Ce module fournit une prise en charge limitée des expressions XPath
pour localiser des éléments dans une arborescence. L'objectif est de
prendre en charge un petit sous-ensemble de la syntaxe abrégée ; un
moteur *XPath* complet sort du cadre du module.


Exemple
-------

Voici un exemple qui démontre certaines des fonctionnalités *XPath* du
module. Nous utilisons le document XML "countrydata" de la section
Parsing XML :

   import xml.etree.ElementTree as ET

   root = ET.fromstring(countrydata)

   # Top-level elements
   root.findall(".")

   # All 'neighbor' grand-children of 'country' children of the top-level
   # elements
   root.findall("./country/neighbor")

   # Nodes with name='Singapore' that have a 'year' child
   root.findall(".//year/..[@name='Singapore']")

   # 'year' nodes that are children of nodes with name='Singapore'
   root.findall(".//*[@name='Singapore']/year")

   # All 'neighbor' nodes that are the second child of their parent
   root.findall(".//neighbor[2]")

Pour du XML avec des espaces de noms, utilisez la notation qualifiée
habituelle "{namespace}tag" :

   # All dublin-core "title" tags in the document
   root.findall(".//{http://purl.org/dc/elements/1.1/}title")


Prise en charge de la syntaxe *XPath*
-------------------------------------

+-------------------------+--------------------------------------------------------+
| Syntaxe                 | Signification                                          |
|=========================|========================================================|
| "tag"                   | Sélectionne tous les éléments enfants avec une balise  |
|                         | donnée. Par exemple, "spam" sélectionne tous les       |
|                         | éléments enfants nommés "spam" et "spam/egg"           |
|                         | sélectionne tous les petits-enfants nommés "egg" dans  |
|                         | les enfants nommés "spam". "{namespace}*" sélectionne  |
|                         | toutes les balises dans l'espace de noms donné,        |
|                         | "{*}spam" sélectionne les balises nommées "spam" dans  |
|                         | n'importe quel (ou aucun) espace de noms et "{}*"      |
|                         | sélectionne seulement les balises qui ne sont pas dans |
|                         | un espace de noms.  Modifié dans la version 3.8: la    |
|                         | prise en charge des caractères génériques étoiles a    |
|                         | été ajoutée.                                           |
+-------------------------+--------------------------------------------------------+
| "*"                     | Sélectionne tous les éléments enfants, y compris les   |
|                         | commentaires et les instructions de traitement. Par    |
|                         | exemple, "*/egg" sélectionne tous les petits-enfants   |
|                         | nommés "egg".                                          |
+-------------------------+--------------------------------------------------------+
| "."                     | Sélectionne le nœud actuel. C'est surtout utile au     |
|                         | début du chemin, pour indiquer qu'il s'agit d'un       |
|                         | chemin relatif.                                        |
+-------------------------+--------------------------------------------------------+
| "//"                    | Sélectionne tous les sous-éléments, à tous les niveaux |
|                         | situés sous l'élément actuel. Par exemple, ".//egg"    |
|                         | sélectionne tous les éléments "egg" dans               |
|                         | l'arborescence entière.                                |
+-------------------------+--------------------------------------------------------+
| ".."                    | Sélectionne l'élément parent. Renvoie "None" si le     |
|                         | chemin tente d'atteindre les ancêtres de l'élément de  |
|                         | départ (l'élément sur lequel "find" a été appelé).     |
+-------------------------+--------------------------------------------------------+
| "[@attrib]"             | Sélectionne tous les éléments qui ont l'attribut       |
|                         | donné.                                                 |
+-------------------------+--------------------------------------------------------+
| "[@attrib='value']"     | Sélectionne tous les éléments pour lesquels l'attribut |
|                         | donné a la valeur donnée. La valeur ne peut pas        |
|                         | contenir de guillemet simple ("'").                    |
+-------------------------+--------------------------------------------------------+
| "[@attrib!='value']"    | Sélectionne tous les éléments pour lesquels l'attribut |
|                         | donné n'a pas la valeur donnée. La valeur ne peut pas  |
|                         | contenir de guillemet simple ("'").  Nouveau dans la   |
|                         | version 3.10.                                          |
+-------------------------+--------------------------------------------------------+
| "[tag]"                 | Sélectionne tous les éléments qui ont un enfant nommé  |
|                         | "tag". Seuls les enfants immédiats sont pris en        |
|                         | charge.                                                |
+-------------------------+--------------------------------------------------------+
| "[.='text']"            | Sélectionne tous les éléments dont le contenu textuel  |
|                         | complet, y compris les descendants, est égal au "text" |
|                         | donné.  Nouveau dans la version 3.7.                   |
+-------------------------+--------------------------------------------------------+
| "[.!='text']"           | Sélectionne tous les éléments dont le contenu textuel  |
|                         | complet, y compris les descendants, n'est pas égal au  |
|                         | "text" donné.  Nouveau dans la version 3.10.           |
+-------------------------+--------------------------------------------------------+
| "[tag='text']"          | Sélectionne tous les éléments qui ont un enfant nommé  |
|                         | "tag" dont le contenu textuel complet, y compris les   |
|                         | descendants, est égal au "text" donné.                 |
+-------------------------+--------------------------------------------------------+
| "[tag!='text']"         | Sélectionne tous les éléments qui ont un enfant nommé  |
|                         | "tag" dont le contenu textuel complet, y compris les   |
|                         | descendants, n'est pas égal au "text" donné.  Nouveau  |
|                         | dans la version 3.10.                                  |
+-------------------------+--------------------------------------------------------+
| "[position]"            | Sélectionne tous les éléments situés à la position     |
|                         | donnée. La position peut être soit un entier (1 est la |
|                         | première position), l'expression "last()" (pour la     |
|                         | dernière position), ou une position relative à la      |
|                         | dernière position (par exemple "last()-1").            |
+-------------------------+--------------------------------------------------------+

Les prédicats (expressions entre crochets) doivent être précédés d'un
nom de balise, d'un astérisque ou d'un autre prédicat. Les prédicats
"position" doivent être précédés d'un nom de balise.


Référence
=========


Fonctions
---------

xml.etree.ElementTree.canonicalize(xml_data=None, *, out=None, from_file=None, **options)

   Fonction de transformation C14N 2.0.

   La canonisation est un moyen de normaliser la sortie XML de manière
   à permettre des comparaisons octet par octet et des signatures
   numériques. Cela réduit la liberté dont disposent les outils de
   sérialisation XML et génère à la place une représentation XML plus
   contrainte. Les principales restrictions concernent le placement
   des déclarations d'espaces de noms, l'ordre des attributs et les
   espaces à ignorer.

   Cette fonction prend une chaîne de données XML (*xml_data*) ou un
   chemin de fichier ou un objet de type fichier (*from_file*) en
   entrée, la convertit sous la forme canonique et l'écrit à l'aide de
   l'objet simili-fichier *out*, s'il est fourni, ou le renvoie sous
   forme de chaîne de texte sinon. Le fichier de sortie reçoit du
   texte, pas des octets. Il doit donc être ouvert en mode texte avec
   l'encodage "utf-8".

   Utilisation typique :

      xml_data = "<root>...</root>"
      print(canonicalize(xml_data))

      with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file:
          canonicalize(xml_data, out=out_file)

      with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file:
          canonicalize(from_file="inputfile.xml", out=out_file)

   Les *options* de configuration sont les suivantes :

   * *with_comments* : définissez cet attribut à vrai pour inclure les
     commentaires (par défaut : faux)

   * *strip_text* : définissez à vrai pour supprimer les espaces avant
     et après le contenu du texte
        (par défaut : faux)

   * *rewrite_prefixes* : définissez à vrai pour remplacer les
     préfixes d'espace de noms par « n{nombre} »
        (par défaut : faux)

   * *qname_aware_tags* : ensemble de noms de balises prenant en
     charge les noms qualifiés dans lesquels les préfixes
        doivent être remplacés dans le contenu du texte (par défaut :
        vide)

   * *qname_aware_attrs* : ensemble de noms d'attributs prenant en
     charge les noms qualifiés dans lesquels les préfixes
        doivent être remplacés dans le contenu du texte (par défaut :
        vide)

   * *exclude_attrs* : ensemble de noms d'attributs qui ne doivent pas
     être sérialisés

   * *exclude_tags* : ensemble de noms de balises qui ne doivent pas
     être sérialisés

   Dans la liste d'options ci-dessus, un « ensemble » fait référence à
   toute collection ou itérable de chaînes, aucun ordre n'est attendu.

   Nouveau dans la version 3.8.

xml.etree.ElementTree.Comment(text=None)

   Fabrique d’éléments de commentaire. Cette fonction crée un élément
   spécial qui sera sérialisé sous forme de commentaire XML par le
   sérialiseur standard. La chaîne de commentaire peut être une chaîne
   d'octets ou une chaîne Unicode. *text* est une chaîne contenant la
   chaîne de commentaire. Renvoie une instance d'élément représentant
   un commentaire.

   Notez que "XMLParser" ignore les commentaires dans l'entrée au lieu
   de créer des objets de commentaire pour eux. Un "ElementTree" ne
   contiendra que des nœuds de commentaires qui ont été insérés dans
   l'arborescence à l'aide de l'une des méthodes d'"Element".

xml.etree.ElementTree.dump(elem)

   Écrit une arborescence d'éléments ou une structure d'éléments dans
   *sys.stdout*. Cette fonction doit être utilisée uniquement pour le
   débogage.

   Le format de sortie exact dépend de l’implémentation. Dans cette
   version, il est écrit sous la forme d'un fichier XML ordinaire.

   *elem* est un élément de l'arborescence ou un élément individuel.

   Modifié dans la version 3.8: la fonction "dump()" préserve
   désormais l'ordre des attributs spécifié par l'utilisateur.

xml.etree.ElementTree.fromstring(text, parser=None)

   Analyse une section XML à partir d'une constante de chaîne.
   Identique à "XML()". *text* est une chaîne contenant des données
   XML. *parser* est une instance d'analyseur facultative. S'il n'est
   pas fourni, l'analyseur standard "XMLParser" est utilisé. Renvoie
   une instance d'"Element".

xml.etree.ElementTree.fromstringlist(sequence, parser=None)

   Analyse un document XML à partir d'une séquence de fragments de
   chaîne. *séquence* est une liste ou une autre séquence contenant
   des fragments de données XML. *parser* est une instance d'analyseur
   facultative. S'il n'est pas fourni, l'analyseur standard
   "XMLParser" est utilisé. Renvoie une instance d'"Element".

   Nouveau dans la version 3.2.

xml.etree.ElementTree.indent(tree, space='  ', level=0)

   Ajoute des espaces au sous-arbre pour indenter visuellement
   l'arborescence. Cela peut être utilisé pour générer une sortie XML
   avec une mise en forme agréable. *tree* peut être un élément ou un
   *ElementTree*. *espace* est la chaîne d'espaces qui est insérée
   pour chaque niveau d'indentation, deux caractères d'espace par
   défaut. Pour indenter des sous-arbres partiels à l'intérieur d'un
   arbre déjà indenté, transmettez le niveau d'indentation initial
   dans *level*.

   Nouveau dans la version 3.9.

xml.etree.ElementTree.iselement(element)

   Vérifie si un objet semble être un objet élément valide. *element*
   est une instance d'élément. Renvoie "True" s'il s'agit d'un objet
   élément.

xml.etree.ElementTree.iterparse(source, events=None, parser=None)

   Parses an XML section into an element tree incrementally, and
   reports what's going on to the user.  *source* is a filename or
   *file object* containing XML data.  *events* is a sequence of
   events to report back.  The supported events are the strings
   ""start"", ""end"", ""comment"", ""pi"", ""start-ns"" and ""end-
   ns"" (the "ns" events are used to get detailed namespace
   information).  If *events* is omitted, only ""end"" events are
   reported. *parser* is an optional parser instance.  If not given,
   the standard "XMLParser" parser is used.  *parser* must be a
   subclass of "XMLParser" and can only use the default "TreeBuilder"
   as a target. Returns an *iterator* providing "(event, elem)" pairs;
   it has a "root" attribute that references the root element of the
   resulting XML tree once *source* is fully read.

   Notez que même si "iterparse()" construit l'arborescence de manière
   incrémentielle, il bloque pendant les lectures sur *source*. En
   tant que tel, il ne convient pas aux applications dans lesquelles
   le blocage pendant les lectures ne peut pas être effectué. Pour une
   analyse entièrement non bloquante, voir "XMLPullParser".

   Note:

     "iterparse()" garantit uniquement qu'il a vu le caractère "">""
     d'une balise de début lorsqu'il émet un événement ""start"", donc
     les attributs sont définis mais le contenu des attributs *text*
     et *tail* n'est pas défini à ce stade. La même chose s'applique
     aux nœuds enfants de l'élément ; ils peuvent être présents ou
     non.Si vous avez besoin d'un élément entièrement rempli,
     recherchez plutôt les événements ""end"".

   Obsolète depuis la version 3.4: l'argument *parser*.

   Modifié dans la version 3.8: les évènements "comment" et "pi" ont
   été ajoutés.

xml.etree.ElementTree.parse(source, parser=None)

   Analyse une section XML dans une arborescence d'éléments. *source*
   est un nom de fichier ou un objet fichier contenant des données
   XML. *parser* (facultatif) est une instance d'analyseur. S'il n'est
   pas fourni, l'analyseur standard "XMLParser" est utilisé. Renvoie
   une instance d'"ElementTree".

xml.etree.ElementTree.ProcessingInstruction(target, text=None)

   Fabrique d’éléments *Processing Instruction* (PI). Cette fonction
   crée un élément spécial qui sera sérialisé en tant qu'instruction
   de traitement XML. *target* est une chaîne contenant la cible PI.
   *text* est une chaîne contenant le contenu de l'instruction de
   traitement (ou PI), s'il est fourni. Renvoie une instance
   d'élément, représentant l'instruction de traitement.

   Note that "XMLParser" skips over processing instructions in the
   input instead of creating PI objects for them. An "ElementTree"
   will only contain processing instruction nodes if they have been
   inserted into to the tree using one of the "Element" methods.

xml.etree.ElementTree.register_namespace(prefix, uri)

   Enregistre un préfixe d'espace de noms. Le registre est global et
   toute correspondance existante pour le préfixe donné ainsi que
   l'URI de l'espace de noms sera supprimé. *prefix* est un préfixe
   d'espace de noms. *uri* est un URI d'espace de noms. Les balises et
   les attributs de cet espace de noms seront sérialisés avec le
   préfixe donné, si possible.

   Nouveau dans la version 3.2.

xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra)

   Fabrique de sous-élément. Cette fonction crée une instance
   d'élément et l'ajoute à un élément existant.

   Le nom de l'élément, les noms d'attributs et les valeurs
   d'attributs peuvent être des chaînes d'octets ou des chaînes
   Unicode. *parent* est l'élément parent. *tag* est le nom du sous-
   élément. *attrib* est un dictionnaire facultatif contenant les
   attributs de l'élément. *extra* contient des attributs
   supplémentaires, donnés sous forme d'arguments nommés. Renvoie une
   instance d'élément.

xml.etree.ElementTree.tostring(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)

   Génère une représentation sous forme de chaîne d'un élément XML, y
   compris tous les sous-éléments. *element* est une instance de
   "Element". *encoding* [1] est l'encodage de sortie (la valeur par
   défaut est US-ASCII). Utilisez "encoding="unicode"" pour générer
   une chaîne Unicode (sinon, une chaîne d'octets est générée).
   *method* vaut ""xml"", ""html"" ou ""text"" (la valeur par défaut
   est ""xml""). *xml_declaration*, *default_namespace* et
   *short_empty_elements* ont la même signification que dans
   "ElementTree.write()". Renvoie une chaîne codée (éventuellement)
   contenant les données XML.

   Modifié dans la version 3.4: Added the *short_empty_elements*
   parameter.

   Modifié dans la version 3.8: Added the *xml_declaration* and
   *default_namespace* parameters.

   Modifié dans la version 3.8: la fonction "tostring()" préserve
   désormais l'ordre des attributs spécifié par l'utilisateur.

xml.etree.ElementTree.tostringlist(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)

   Génère une représentation sous forme de chaîne d'un élément XML, y
   compris tous les sous-éléments. *element* est une instance de
   "Element". *encoding* [1] est l'encodage de sortie (la valeur par
   défaut est US-ASCII). Utilisez "encoding="unicode"" pour générer
   une chaîne Unicode (sinon, une chaîne d'octets est générée).
   *method* vaut ""xml"", ""html"" ou ""text"" (la valeur par défaut
   est ""xml""). *xml_declaration*, *default_namespace* et
   *short_empty_elements* ont la même signification que dans
   "ElementTree.write()". Renvoie une liste de chaînes codées
   (éventuellement) contenant les données XML. Elle ne garantit aucune
   séquence spécifique, seulement "b"".join(tostringlist(element)) ==
   tostring(element)".

   Nouveau dans la version 3.2.

   Modifié dans la version 3.4: Added the *short_empty_elements*
   parameter.

   Modifié dans la version 3.8: Added the *xml_declaration* and
   *default_namespace* parameters.

   Modifié dans la version 3.8: la fonction "tostringlist()" préserve
   désormais l'ordre des attributs spécifié par l'utilisateur.

xml.etree.ElementTree.XML(text, parser=None)

   Analyse une section XML à partir d'une constante de chaîne. Cette
   fonction peut être utilisée pour intégrer des « littéraux XML »
   dans du code Python. *text* est une chaîne contenant des données
   XML. *parser*, facultatif, est une instance d'analyseur. S'il n'est
   pas fourni, l'analyseur standard "XMLParser" est utilisé. Renvoie
   une instance d'"Element".

xml.etree.ElementTree.XMLID(text, parser=None)

   Analyse une section XML à partir d'une constante de chaîne et
   renvoie également un dictionnaire qui fait correspondre les
   identifiants d'éléments aux éléments. *text* est une chaîne
   contenant des données XML. *parser*, facultatif, est une instance
   d'analyseur. S'il n'est pas fourni, l'analyseur standard
   "XMLParser" est utilisé. Renvoie un *n*-uplet contenant une
   instance d'"Element" et un dictionnaire.


Prise en charge de *XInclude*
=============================

Ce module fournit une prise en charge limitée des directives XInclude,
via le module d'assistance "xml.etree.ElementInclude". Ce module peut
être utilisé pour insérer des sous-arbres et des chaînes de texte dans
des arborescences d'éléments, en fonction des informations contenues
dans l'arborescence.


Exemple
-------

Voici un exemple qui montre l'utilisation du module *XInclude*. Pour
inclure un document XML dans le document actuel, utilisez l'élément
"{http://www.w3.org/2001/XInclude}include", définissez l'attribut
**parse** sur ""xml""  et utilisez l'attribut **href** pour spécifier
le document à inclure.

   <?xml version="1.0"?>
   <document xmlns:xi="http://www.w3.org/2001/XInclude">
     <xi:include href="source.xml" parse="xml" />
   </document>

Par défaut, l'attribut **href** est traité comme un nom de fichier.
Vous pouvez utiliser des chargeurs personnalisés pour remplacer ce
comportement. Notez également que l'assistant standard ne prend pas en
charge la syntaxe *XPointer*.

Pour traiter ce fichier, chargez-le comme d'habitude et passez
l'élément racine au module "xml.etree.ElementTree" :

   from xml.etree import ElementTree, ElementInclude

   tree = ElementTree.parse("document.xml")
   root = tree.getroot()

   ElementInclude.include(root)

Le module *ElementInclude* remplace l'élément
"{http://www.w3.org/2001/XInclude}include" par l'élément racine du
document **source.xml**. Le résultat pourrait ressembler à ceci :

   <document xmlns:xi="http://www.w3.org/2001/XInclude">
     <para>This is a paragraph.</para>
   </document>

Si l'attribut **parse** est omis, sa valeur par défaut est ""xml"".
L'attribut *href* est obligatoire.

Pour inclure un document texte, utilisez l'élément
"{http://www.w3.org/2001/XInclude}include" et définissez l'attribut
**parse** sur ""text"" :

   <?xml version="1.0"?>
   <document xmlns:xi="http://www.w3.org/2001/XInclude">
     Copyright (c) <xi:include href="year.txt" parse="text" />.
   </document>

Le résultat pourrait ressembler à ceci :

   <document xmlns:xi="http://www.w3.org/2001/XInclude">
     Copyright (c) 2003.
   </document>


Référence
=========


Fonctions
---------

xml.etree.ElementInclude.default_loader(href, parse, encoding=None)

   Chargeur par défaut. Ce chargeur par défaut lit une ressource
   incluse à partir du disque. *href* est une URL. *parse* (le mode
   d'analyse) vaut soit ""xml"", soit ""text"". *encoding* est un
   encodage de texte facultatif. S'il n'est pas indiqué, l'encodage
   est "utf-8". Renvoie la ressource développée. Si le mode d'analyse
   est ""xml"", il s'agit d'une instance d'"ElementTree". Si le mode
   d'analyse est ""text"", il s'agit d'une chaîne Unicode. Si le
   chargeur échoue, il peut renvoyer "None" ou lever une exception.

xml.etree.ElementInclude.include(elem, loader=None, base_url=None, max_depth=6)

   Cette fonction étend les directives *XInclude*. *elem* est
   l'élément racine. *loader* est un chargeur de ressources
   facultatif. S'il est omis, la valeur par défaut est
   "default_loader()". S'il est donné, il doit s'agir d'un appelable
   qui implémente la même interface que "default_loader()". *base_url*
   est l'URL de base du fichier d'origine, pour résoudre les
   références relatives au fichier à inclure. *max_degree* est le
   nombre maximum d'inclusions récursives. La limite existe pour
   réduire le risque d’explosion de contenu malveillant. Passez une
   valeur négative pour désactiver la limite.

   Renvoie la ressource développée. Si le mode d'analyse est ""xml"",
   il s'agit d'une instance *ElementTree*. Si le mode d'analyse est
   ""text"", il s'agit d'une chaîne Unicode. Si le chargeur échoue, il
   peut renvoyer "None" ou lever une exception.

   Modifié dans la version 3.9: Added the *base_url* and *max_depth*
   parameters.


Objets *Element*
----------------

class xml.etree.ElementTree.Element(tag, attrib={}, **extra)

   Classe Element.  Cette classe définit l'interface Element et
   fournit une implémentation de référence de cette interface.

   Le nom de l'élément, les noms d'attributs et les valeurs
   d'attributs peuvent être des chaînes d'octets ou des chaînes
   Unicode. *tag* est le nom de l'élément. *attrib* est un
   dictionnaire facultatif contenant les attributs des éléments.
   *extra* contient des attributs supplémentaires, donnés sous forme
   d'arguments nommés.

   tag

      Chaîne identifiant le type de données que cet élément représente
      (en d'autres termes, le type d'élément).

   text
   tail

      Ces attributs peuvent être utilisés pour contenir des données
      supplémentaires associées à l'élément. Leurs valeurs sont
      généralement des chaînes mais peuvent être n'importe quel objet
      spécifique à une application. Si l'élément est créé à partir
      d'un fichier XML, l'attribut *text* contient soit le texte entre
      la balise de début de l'élément et sa première balise enfant ou
      de fin, soit "None" ; l'attribut *tail* contient soit le texte
      entre la balise de fin de l'élément et la balise suivante, soit
      "None". Pour les données XML

         <a><b>1<c>2<d/>3</c></b>4</a>

      les attributs *text* et *tail* de l'élément *a* valent "None",
      l'attribut *text* de l'élément *b* vaut ""1"" et *tail* vaut
      ""4"", l'attribut *text* de l'élément *c* vaut ""2"" et *tail*
      vaut "None", et l'attribut *text* de l'élément *d* vaut "None"
      et *tail* vaut ""3"".

      Pour récupérer le texte interne d'un élément, voir "itertext()",
      par exemple """.join(element.itertext())".

      Les applications peuvent stocker des objets arbitraires dans ces
      attributs.

   attrib

      Dictionnaire contenant les attributs de l'élément. Notez que
      même si la valeur *attrib* est toujours un véritable
      dictionnaire Python mutable, une implémentation d'*ElementTree*
      peut choisir d'utiliser une autre représentation interne et de
      créer le dictionnaire uniquement si quelqu'un le demande. Pour
      profiter de telles implémentations, utilisez les méthodes de
      dictionnaire ci-dessous autant que possible.

   Les méthodes dictionnaire-compatibles suivantes traitent les
   attributs de l'élément.

   clear()

      Réinitialise un élément. Cette fonction supprime tous les sous-
      éléments, efface tous les attributs et définit les attributs
      *text* et *tail* sur "None".

   get(key, default=None)

      Accède à l'attribut de l'élément nommé *key*.

      Renvoie la valeur de l'attribut ou *default* si l'attribut n'a
      pas été trouvé.

   items()

      Renvoie les attributs de l'élément comme une séquence de paire
      (nom, valeur). Les attributs sont renvoyés dans un ordre
      arbitraire.

   keys()

      Renvoie les noms d'attributs des éléments sous forme de liste.
      Les noms sont renvoyés dans un ordre arbitraire.

   set(key, value)

      Change l'attribut *key* à l'élément *value*.

   Les méthodes suivantes traitent les éléments enfants (sous-
   éléments).

   append(subelement)

      Ajoute l'élément *subelement* à la fin de la liste interne des
      sous-éléments de cet élément. Lève une "TypeError" si
      *subelement* n'est pas un "Element".

   extend(subelements)

      Ajoute *subelements* à partir d'un objet séquence avec zéro ou
      plusieurs éléments. Lève une "TypeError" si un sous-élément
      n'est pas un "Element".

      Nouveau dans la version 3.2.

   find(match, namespaces=None)

      Recherche le premier sous-élément correspondant à *match*.
      *match* peut être un nom de balise ou un path. Renvoie une
      instance d'élément ou "None". *namespaces* est un tableau de
      correspondances facultatif de préfixes d'espaces de noms vers
      des noms complets. Passez "''" comme préfixe pour déplacer tous
      les noms de balises sans préfixe dans l'expression dans l'espace
      de noms donné.

   findall(match, namespaces=None)

      Recherche tous les sous-éléments correspondants, par nom de
      balise ou path. Renvoie une liste contenant tous les éléments
      correspondants dans l'ordre du document. *namespaces* est un
      tableau de correspondances facultatif de préfixes d'espaces de
      noms vers des noms complets. Passez "''" comme préfixe pour
      déplacer tous les noms de balises sans préfixe dans l'expression
      dans l'espace de noms donné.

   findtext(match, default=None, namespaces=None)

      Recherche le texte du premier sous-élément correspondant à
      *match*. *match* peut être un nom de balise ou un path. Renvoie
      le contenu textuel du premier élément correspondant, ou
      *default* si aucun élément n'a été trouvé. Notez que si
      l'élément correspondant n'a pas de contenu textuel, une chaîne
      vide est renvoyée. *namespaces* est un tableau de
      correspondances facultatif de préfixes d'espaces de noms vers
      des noms complets. Passez "''" comme préfixe pour déplacer tous
      les noms de balises sans préfixe dans l'expression dans l'espace
      de noms donné.

   insert(index, subelement)

      Insère le *subelement* à la position donnée dans cet élément.
      Lève une "TypeError" si *subelement* n'est pas un "Element".

   iter(tag=None)

      Crée un *itérateur* sur l'arbre  avec l'élément actuel comme
      racine. L'itérateur parcourt cet élément et tous les éléments
      situés en dessous, dans l'ordre du document (profondeur en
      premier). Si *tag* n'est pas "None" ou "'*'", seuls les éléments
      dont la balise est égale à *tag* sont renvoyés par l'itérateur.
      Si l'arborescence est modifiée au cours de l'itération, le
      résultat est indéfini.

      Nouveau dans la version 3.2.

   iterfind(match, namespaces=None)

      Recherche tous les sous-éléments correspondants, par nom de
      balise ou path. Renvoie un itérable donnant tous les éléments
      correspondants dans l'ordre du document. *namespaces* est un
      tableau de correspondances facultatif de préfixes d'espaces de
      noms vers des noms complets.

      Nouveau dans la version 3.2.

   itertext()

      Crée un itérateur de texte. L'itérateur parcourt cet élément et
      tous les sous-éléments, dans l'ordre du document, et renvoie
      tout le texte interne.

      Nouveau dans la version 3.2.

   makeelement(tag, attrib)

      Crée un nouvel objet élément du même type que cet élément.
      N'appelez pas cette méthode, utilisez plutôt la fonction de
      fabrique "SubElement()".

   remove(subelement)

      Supprime le *subelement* de l'élément. Contrairement aux
      méthodes *find**, cette méthode compare les éléments en fonction
      de l'identité de l'instance, et non de la valeur ou du contenu
      de la balise.

   Les objets "Element" prennent également en charge les méthodes de
   type séquence suivantes pour travailler avec des sous éléments :
   "__delitem__()", "__getitem__()", "__setitem__()", "__len__()".

   Attention : les éléments sans sous-élément sont évalués comme
   "False". Ce comportement changera dans les versions futures.
   Utilisez plutôt un test spécifique "len(elem)" ou "elem is None".

      element = root.find('foo')

      if not element:  # careful!
          print("element not found, or element has no subelements")

      if element is None:
          print("element not found")

   Avant Python 3.8, l'ordre de sérialisation des attributs XML des
   éléments était artificiellement rendu prévisible en classant les
   attributs par leur nom. Sur la base de l'ordre désormais garanti
   des dictionnaires, cette réorganisation arbitraire a été supprimée
   dans Python 3.8 pour préserver l'ordre dans lequel les attributs
   ont été initialement analysés ou créés par le code utilisateur.

   En général, le code utilisateur doit essayer de ne pas dépendre
   d'un ordre spécifique des attributs, étant donné que la
   documentation de référence XML exclut explicitement que l'ordre des
   attributs soit porteur d'information. Le code doit être prêt à
   gérer tout ordre en entrée. Dans les cas où une sortie XML
   déterministe est requise, par exemple pour la signature
   cryptographique ou les ensembles de données de test, la
   sérialisation canonique est disponible avec la fonction
   "canonicalize()".

   Dans les cas où la sortie canonique n'est pas applicable mais où un
   ordre d'attributs spécifique est quand même souhaitable en sortie,
   le code doit viser à créer les attributs directement dans l'ordre
   souhaité, afin d'éviter des inadéquations de perception pour les
   lecteurs du code. Dans les cas où cela est difficile à réaliser,
   une recette comme ci-dessous peut être appliquée avant la
   sérialisation pour appliquer un ordre indépendant de la création de
   l'élément :

      def reorder_attributes(root):
          for el in root.iter():
              attrib = el.attrib
              if len(attrib) > 1:
                  # adjust attribute order, e.g. by sorting
                  attribs = sorted(attrib.items())
                  attrib.clear()
                  attrib.update(attribs)


Objets *ElementTree*
--------------------

class xml.etree.ElementTree.ElementTree(element=None, file=None)

   Classe enveloppant *ElementTree*. Cette classe représente une
   hiérarchie d'éléments entière et ajoute une prise en charge
   supplémentaire pour la sérialisation vers et depuis le XML
   standard.

   *element* est l'élément racine. L'arborescence est initialisée avec
   le contenu du fichier XML *file* s'il est fourni.

   _setroot(element)

      Remplace l'élément racine de cette arborescence. Cela supprime
      le contenu actuel de l'arborescence et le remplace par l'élément
      donné. À utiliser avec précaution. *element* est une instance
      d'élément.

   find(match, namespaces=None)

      Comme "Element.find()", commence à la racine de l'arbre.

   findall(match, namespaces=None)

      Identique à "Element.findall()", en commençant à la racine de
      l'arborescence.

   findtext(match, default=None, namespaces=None)

      Identique à "Element.findtext()", en commençant à la racine de
      l'arborescence.

   getroot()

      Renvoie l'élément racine de l'arbre.

   iter(tag=None)

      Crée et renvoie un itérateur d'arborescence pour l'élément
      racine. L'itérateur parcourt tous les éléments de cette
      arborescence, dans l'ordre des sections. *tag* est la balise à
      rechercher (la valeur par défaut est de renvoyer tous les
      éléments).

   iterfind(match, namespaces=None)

      Identique à "Element.iterfind()", en commençant à la racine de
      l'arborescence.

      Nouveau dans la version 3.2.

   parse(source, parser=None)

      Charge une section XML externe dans cette arborescence
      d'éléments. *source* est un nom de fichier ou un *objet
      fichier*. *parser*, facultatif, est une instance d'analyseur.
      S'il n'est pas fourni, l'analyseur standard "XMLParser" est
      utilisé. Renvoie l'élément racine de la section.

   write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml', *, short_empty_elements=True)

      Écrit l'arborescence des éléments dans un fichier, au format
      XML. *file* est un nom de fichier ou un *objet fichier* ouvert
      en écriture. *encoding* [1] est l'encodage de sortie (la valeur
      par défaut est US-ASCII). *xml_declaration* contrôle si une
      déclaration XML doit être ajoutée au fichier. Utilisez "False"
      pour jamais, "True" pour toujours, "None" pour seulement si ce
      n'est pas de l'US-ASCII ou de l'UTF-8 ou de l'Unicode (la valeur
      par défaut est "None"). *default_namespace* définit l'espace de
      noms XML par défaut (pour ""xmlns""). *method* vaut ""xml"",
      ""html"" ou ""text"" (la valeur par défaut est ""xml""). Le
      paramètre nommé (uniquement) *short_empty_elements* contrôle le
      formatage des éléments qui ne contiennent aucun contenu. Si
      c'est "True" (valeur par défaut), ils sont écrits sous la forme
      d'une seule balise auto-fermée, sinon ils sont écrits sous la
      forme d'une paire de balises de début-fin.

      La sortie est une chaîne ("str") ou du binaire ("bytes"). C'est
      contrôlé par l'argument *encoding*. Si *encoding* est
      ""unicode"", la sortie est une chaîne ; sinon, c'est binaire.
      Notez que cela peut entrer en conflit avec le type de *fichier*
      s'il s'agit d'un *objet fichier* déjà ouvert ; assurez-vous de
      ne pas essayer d'écrire une chaîne dans un flux binaire et vice
      versa.

      Modifié dans la version 3.4: Added the *short_empty_elements*
      parameter.

      Modifié dans la version 3.8: la méthode "write()" préserve
      désormais l'ordre des attributs spécifié par l'utilisateur.

Voici le fichier XML à manipuler :

   <html>
       <head>
           <title>Example page</title>
       </head>
       <body>
           <p>Moved to <a href="http://example.org/">example.org</a>
           or <a href="http://example.com/">example.com</a>.</p>
       </body>
   </html>

Exemple de modification de l'attribut *target* de chaque lien dans le
premier paragraphe :

   >>> from xml.etree.ElementTree import ElementTree
   >>> tree = ElementTree()
   >>> tree.parse("index.xhtml")
   <Element 'html' at 0xb77e6fac>
   >>> p = tree.find("body/p")     # Finds first occurrence of tag p in body
   >>> p
   <Element 'p' at 0xb77ec26c>
   >>> links = list(p.iter("a"))   # Returns list of all links
   >>> links
   [<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]
   >>> for i in links:             # Iterates through all found links
   ...     i.attrib["target"] = "blank"
   >>> tree.write("output.xhtml")


Objets *QName*
--------------

class xml.etree.ElementTree.QName(text_or_uri, tag=None)

   Surcouche à *QName*. Cela peut être utilisé pour envelopper une
   valeur d'attribut *QName*, afin d'obtenir une gestion appropriée de
   l'espace de noms en sortie. *text_or_uri* est une chaîne contenant
   la valeur *QName*, sous la forme *{uri}local* ou, si l'argument
   *tag* est donné, la partie URI d'un *QName*. Si *tag* est donné, le
   premier argument est interprété comme un URI et cet argument est
   interprété comme un nom local. Les instances "QName" sont opaques.


Objets *TreeBuilder*
--------------------

class xml.etree.ElementTree.TreeBuilder(element_factory=None, *, comment_factory=None, pi_factory=None, insert_comments=False, insert_pis=False)

   Générateur de structure d'éléments générique. Ce constructeur
   convertit une séquence d'appels de méthode *start*, *data*, *end*,
   *comment* et *pi* en une structure d'éléments bien formée. Vous
   pouvez utiliser cette classe pour créer une structure d'éléments à
   l'aide d'un analyseur XML personnalisé ou d'un analyseur pour un
   autre type de format XML.

   *element_factory*, lorsqu'il est donné, doit être un appelable
   acceptant deux arguments positionnels : une balise et un
   dictionnaire d'attributs. Elle est censée renvoyer une nouvelle
   instance d'élément.

   Les fonctions *comment_factory* et *pi_factory*, lorsqu'elles sont
   données, doivent se comporter comme les fonctions "Comment()" et
   "ProcessingInstruction()" pour créer des commentaires et des
   instructions de traitement. Lorsqu’elles ne sont pas fournies, les
   fabriques par défaut sont utilisées. Lorsque *insert_comments* ou
   *insert_pis* sont vraies, les commentaires et instructions de
   traitement sont insérés dans l'arborescence s'ils apparaissent dans
   l'élément racine (mais pas à l'extérieur de celui-ci).

   close()

      Vide les tampons du générateur et renvoie l'élément de document
      de niveau supérieur. Renvoie une instance d'"Element".

   data(data)

      Ajoute du texte à l'élément courant.  *data* est une chaîne de
      caractères.  Cela peut être une chaîne d'octets ou une chaîne
      Unicode.

   end(tag)

      Ferme l'élément courant.  *tag* est le nom de l'élément.
      Renvoie l'élément fermé.

   start(tag, attrs)

      Ouvre un nouvel élément. *tag* est le nom de l'élément. *attrs*
      est un dictionnaire contenant les attributs de l'élément.
      Renvoie l'élément ouvert.

   comment(text)

      Crée un commentaire avec le *text* donné. Si "insert_comments"
      est vrai, cela l'ajoute également à l'arborescence.

      Nouveau dans la version 3.8.

   pi(target, text)

      Creates a process instruction with the given *target* name and
      *text*. If "insert_pis" is true, this will also add it to the
      tree.

      Nouveau dans la version 3.8.

   De plus, un objet "TreeBuilder" personnalisé peut fournir les
   méthodes suivantes :

   doctype(name, pubid, system)

      Gère une déclaration *doctype*. *name* est le nom du type de
      document. *pubid* est l'identifiant public. *system* est
      l'identifiant du système. Cette méthode n'existe pas sur la
      classe par défaut "TreeBuilder".

      Nouveau dans la version 3.2.

   start_ns(prefix, uri)

      Est appelée chaque fois que l'analyseur rencontre une nouvelle
      déclaration d'espace de noms, avant le rappel "start()" pour
      l'élément d'ouverture qui le définit. *prefix* est "''" pour
      l'espace de noms par défaut et le nom du préfixe d'espace de
      noms déclaré dans le cas contraire. *uri* est l'URI de l'espace
      de noms.

      Nouveau dans la version 3.8.

   end_ns(prefix)

      Est appelée après le rappel "end()" d'un élément qui a déclaré
      une correspondance de préfixe d'espace de noms, avec le nom du
      *prefix* qui passe hors de portée.

      Nouveau dans la version 3.8.

class xml.etree.ElementTree.C14NWriterTarget(write, *, with_comments=False, strip_text=False, rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None, exclude_attrs=None, exclude_tags=None)

   Écrivain C14N 2.0. Les arguments sont les mêmes que pour la
   fonction "canonicalize()". Cette classe ne construit pas
   d'arborescence mais traduit les événements de rappel directement
   sous une forme sérialisée à l'aide de la fonction *write*.

   Nouveau dans la version 3.8.


Objets *XMLParser*
------------------

class xml.etree.ElementTree.XMLParser(*, target=None, encoding=None)

   Cette classe est l’élément de base du module. Elle utilise
   "xml.parsers.expat" pour une analyse efficace du XML et fonctionne
   à base d'événements. Elle peut être alimentée en données XML de
   manière incrémentielle avec la méthode "feed()", et les événements
   d'analyse sont traduits en une API à flux poussé – en appelant les
   méthodes de rappel de l'objet *target*. Si *target* est omis, le
   "TreeBuilder" standard est utilisé. Si *encoding* [1] est donné, la
   valeur remplace l'encodage spécifié dans le fichier XML.

   Modifié dans la version 3.8: les paramètres sont désormais nommés
   uniquement. L'argument *html* n'est plus pris en charge.

   close()

      Termine l'envoi des données à l'analyseur. Renvoie le résultat
      de l'appel de la méthode "close()" de la *target* passée lors de
      la construction ; par défaut, il s'agit de l'élément de plus
      haut niveau du document.

   feed(data)

      Fournit des données à l’analyseur. *data* est une donnée
      encodée.

   flush()

      Triggers parsing of any previously fed unparsed data, which can
      be used to ensure more immediate feedback, in particular with
      Expat >=2.6.0. The implementation of "flush()" temporarily
      disables reparse deferral with Expat (if currently enabled) and
      triggers a reparse. Disabling reparse deferral has security
      consequences; please see
      "xml.parsers.expat.xmlparser.SetReparseDeferralEnabled()" for
      details.

      Note that "flush()" has been backported to some prior releases
      of CPython as a security fix.  Check for availability of
      "flush()" using "hasattr()" if used in code running across a
      variety of Python versions.

      Nouveau dans la version 3.11.9.

   "XMLParser.feed()" appelle la méthode "start(tag, attrs_dict)" de
   *target* pour chaque balise d'ouverture, sa méthode "end(tag)" pour
   chaque balise de fermeture, et les données sont traitées par la
   méthode "data(data)". Pour d'autres méthodes de rappel prises en
   charge, consultez la classe "TreeBuilder". "XMLParser.close()"
   appelle la méthode "close()" de *target*. "XMLParser" peut être
   utilisée pour autre chose que seulement construire une structure
   arborescente. Voici un exemple de comptage de la profondeur
   maximale d'un fichier XML :

      >>> from xml.etree.ElementTree import XMLParser
      >>> class MaxDepth:                     # The target object of the parser
      ...     maxDepth = 0
      ...     depth = 0
      ...     def start(self, tag, attrib):   # Called for each opening tag.
      ...         self.depth += 1
      ...         if self.depth > self.maxDepth:
      ...             self.maxDepth = self.depth
      ...     def end(self, tag):             # Called for each closing tag.
      ...         self.depth -= 1
      ...     def data(self, data):
      ...         pass            # We do not need to do anything with data.
      ...     def close(self):    # Called when all data has been parsed.
      ...         return self.maxDepth
      ...
      >>> target = MaxDepth()
      >>> parser = XMLParser(target=target)
      >>> exampleXml = """
      ... <a>
      ...   <b>
      ...   </b>
      ...   <b>
      ...     <c>
      ...       <d>
      ...       </d>
      ...     </c>
      ...   </b>
      ... </a>"""
      >>> parser.feed(exampleXml)
      >>> parser.close()
      4


Objets *XMLPullParser*
----------------------

class xml.etree.ElementTree.XMLPullParser(events=None)

   Analyseur à flux tiré adapté aux applications non bloquantes. Son
   API côté entrée est similaire à celle de "XMLParser", mais au lieu
   de pousser les appels vers une cible de rappel, "XMLPullParser"
   collecte une liste interne d'événements d'analyse et permet à
   l'utilisateur de la lire. *events* est une séquence d'événements à
   signaler. Les événements pris en charge sont les chaînes ""start"",
   ""end"", ""comment"", ""pi"", ""start-ns"" et ""end-ns"" (les
   événements ""ns"" sont utilisés pour obtenir des informations
   détaillées sur les espaces de noms). Si *events* est omis, seuls
   les événements ""end"" sont rapportés.

   feed(data)

      Transmet les données d’octets à l’analyseur.

   flush()

      Triggers parsing of any previously fed unparsed data, which can
      be used to ensure more immediate feedback, in particular with
      Expat >=2.6.0. The implementation of "flush()" temporarily
      disables reparse deferral with Expat (if currently enabled) and
      triggers a reparse. Disabling reparse deferral has security
      consequences; please see
      "xml.parsers.expat.xmlparser.SetReparseDeferralEnabled()" for
      details.

      Note that "flush()" has been backported to some prior releases
      of CPython as a security fix.  Check for availability of
      "flush()" using "hasattr()" if used in code running across a
      variety of Python versions.

      Nouveau dans la version 3.11.9.

   close()

      Signale à l'analyseur que le flux de données est terminé.
      Contrairement à "XMLParser.close()", cette méthode renvoie
      toujours "None". Tous les événements non encore récupérés
      lorsque l'analyseur est fermé peuvent toujours être lus avec
      "read_events()".

   read_events()

      Renvoie un itérateur sur les événements qui ont été rencontrés
      dans les données fournies à l'analyseur. L'itérateur génère des
      paires "(event, elem)", où *event* est une chaîne représentant
      le type d'événement (par exemple ""end"") et *elem* est l'objet
      "Element" rencontré, ou une autre valeur de contexte comme suit.

      * "start", "end" : l'élément actuel.

      * "comment", "pi" : le commentaire ou l'instruction de
        traitement actuel

      * "start-ns" : couple "(prefix, uri)" nommant la correspondance
        d'espace de noms déclarée.

      * "end-ns" : "None" (cela peut changer dans une version future)

      Les événements fournis lors d'un appel précédent à
      "read_events()" ne seront plus renvoyés. Les événements sont
      consommés à partir de la file d'attente interne uniquement
      lorsqu'ils sont récupérés de l'itérateur, donc plusieurs
      lecteurs itérant en parallèle sur les itérateurs obtenus à
      partir de "read_events()" auront des résultats imprévisibles.

   Note:

     "XMLPullParser" garantit uniquement qu'il a vu le caractère "">""
     d'une balise de début lorsqu'il émet un événement ""start"", donc
     les attributs sont définis, mais le contenu des attributs *text*
     et *tail* n'est pas défini à ce stade. La même chose s'applique
     aux nœuds enfants de l'élément ; ils peuvent être présents ou
     non.Si vous avez besoin d'un élément entièrement rempli,
     recherchez plutôt les événements ""end"".

   Nouveau dans la version 3.4.

   Modifié dans la version 3.8: les évènements "comment" et "pi" ont
   été ajoutés.


Exceptions
----------

class xml.etree.ElementTree.ParseError

   Erreur d'analyse XML, générée par les différentes méthodes
   d'analyse de ce module lorsque l'analyse échoue. La représentation
   sous forme de chaîne d'une instance de cette exception contient un
   message d'erreur convivial. De plus, elle possède les attributs
   suivants :

   code

      Code d'erreur numérique de l'analyseur *expat*. Voir la
      documentation de "xml.parsers.expat" pour la liste des codes
      d'erreur et leur signification.

   position

      Un *n*-uplet de numéros de *ligne* et *colonne* indiquant le
      lieu d'apparition de l'erreur.

-[ Notes ]-

[1] La chaîne de caractères encodée inclue dans la sortie XML doit
    être conforme aux standards. Par exemple, ""UTF-8"" est valide,
    mais pas ""UTF8"".  Voir https://www.w3.org/TR/2006/REC-
    xml11-20060816/#NT-EncodingDecl et
    https://www.iana.org/assignments/character-sets/character-
    sets.xhtml.
