Please note, this is a STATIC archive of website developer.mozilla.org from November 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Traitement de XML avec E4X

Cette page vient d'être traduite, mais elle a besoin d'un relecteur différent du traducteur. Pensez également à toujours vérifier le contenu avec sa toute dernière version en anglais.

Introduit dans JavaScript 1.6

Traitement de XML avec E4X

Introduit pour la première fois dans JavaScript 1.6, E4X ajoute un objet XML natif au langage JavaScript, ainsi qu'une syntaxe pour intégrer des document XML littéraux dans du code JavaScript.

Une définition complète d'E4X peut être trouvé dans la spécification Ecma-357 (en anglais). Cet chapitre fournit un aperçu pratique du langage ; il ne s'agit pas d'une référence complète.

Problèmes de compatibilité

Avant que l'élément <script> soit couramment géré dans les navigateurs, il n'était pas rare de voir le JavaScript intégré dans une page entouré de balises de commentaires HTML pour empêcher les navigateurs ne connaissant pas <script> d'afficher le code JavaScript à l'utilisateur. Cette pratique n'est plus nécessaire, mais reste visible dans d'anciens codes. Pour des raisons de compatibilité ascendante, E4X ignore par défaut les commentaires et sections CDATA. Il est possible d'ajouter un paramètre e4x=1 à une balise <script> pour désactiver cette restriction :

<script type="text/javascript;e4x=1">
...
</script>

Création d'un objet XML

E4X permet de créer un objet XML de deux manières. La première est de passer une chaîne au constructeur XML :

 var langages = new XML('<langages type="dynamique"><lang>JavaScript</lang><lang>Python</lang></langages>');

La seconde est d'intégrer le XML directement dans un script, comme littéral XML :

 var langages = <langages type="dynamique">
   <lang>JavaScript</lang>
   <lang>Python</lang>
 </langages>;

Dans les deux cas, l'objet résultat sera un objet XML E4X, qui permet d'utiliser une syntaxe pratique pour l'accès et la modification des données encapsulées.

Bien que l'objet XML ressemble et se comporte d'une manière similaire à un objet JavaScript normal, ce n'est pas tout à fait la même chose. E4X introduit une nouvelle syntaxe qui ne fonctionne qu'avec les objets XML E4X. La syntaxe est conçue pour être familière aux programmeurs JavaScript, mais E4X ne fournit pas une correspondance directe entre XML et les objets JavaScript natifs ; juste l'illusion qu'il y en a une.

Utilisation d'attributs

Après avoir exécuté l'exemple ci-dessus, la variable langages fait référence à un objet XML correspondant au nœud <langages> dans le document XML. Ce nœud a un attribut, type, qui peut être consulté et modifié de différentes manières :

 alert(langages.@type); // Affiche "dynamique"
 langages.@type = "agile";
 alert(langages.@type); // Affiche "agile"
 alert(langages.toString());
 /* Affiche :
   <langages type="agile"><lang>JavaScript</lang><lang>Python</lang></langages>
 */

Utilisation d'objets XML

Les objets XML fournissent un certain nombre de méthodes pour inspecter et mettre à jour leur contenu. Ils permettent d'utiliser la notation classique de JavaScript avec des points et [], mais plutôt que d'accéder à des propriétés de l'objet, E4X surcharge ces opérateurs pour accéder aux enfants de l'élément :

var personne = <personne>
  <nom>Jean Dupont</nom>
  <aime>
    <os>Linux</os>
    <navigateur>Firefox</navigateur>
    <langage>JavaScript</langage>
    <langage>Python</langage>
  </aime>
</personne>;

alert(personne.nom); // Jean Dupont
alert(personne['nom']); // Jean Dupont
alert(personne.aime.navigateur); // Firefox
alert(personne['aime'].navigateur); // Firefox

Si l'on accède à quelque chose qui correspond à plus d'un élément, on reçoit une XMLList :

alert(personne.aime.langage.length()); // 2

Comme avec le DOM, * peut servir à accéder à tous les nœuds enfants :

alert(personne.aime.*.length()); // 4

Alors que l'opérateur . accède aux enfants directs du nœud, l'opérateur .. accède à tous les enfants quel que soit leur niveau de profondeur :

alert(personne..*.length()); // 11

La méthode length() renvoie ici 11 car tant les éléments que les nœuds texte font partie de la XMLList résultante.

Les objets représentant des éléments XML fournissent un bon nombre de méthodes utiles, dont certaines sont illustrées ci-dessous : TODO : Ajouter toutes les méthodes à la référence JavaScript, et les lier depuis cette section

alert(personne.nom.text()); // Jean Dupont

var xml = personne.toXMLString(); // Une chaîne contenant le XML

var copiePersonne = personne.copy(); // Une copie profonde de l'objet XML

var enfant = person.child(1); // Le second nœud enfant ; dans ce cas l'élément <aime>

Utilisation de XMLLists

Outre l'objet XML, E4X introduit un objet XMLList. XMLList est utilisé pour représenter une collection ordonnée d'objets XML ; par exemple, une liste d'éléments. Pour poursuivre avec l'exemple ci-dessus, on peut accéder à une XMLList des éléments <lang> dans la page comme ceci :

 var langs = langages.lang;

XMLList fournit une méthode length() qui peut être utilisée pour trouver le nombre d'éléments contenus :

 alert(langages.lang.length());

Notez que contrairement aux tableaux JavaScript, length est une méthode et non une propriété, et doit donc être appelée avec des parenthèses comme ceci : length().

Il est possible de parcourir les éléments correspondants comme ceci :

 for (var i = 0; i < langages.lang.length(); i++) {
     alert(langages.lang[i].toString());
 }

Ici on utilise une syntaxe identique à celle utilisée pour accéder à des éléments numérotés dans un tableau. Malgré ces similarités avec les tableaux normaux, XMLList ne gère pas les méthodes d'Array comme forEach, et les méthodes génériques comme Array.forEach() ne sont pas compatibles avec les objets XMLList.

Il est également possible d'utiliser l'instruction for each...in introduite dans JavaScript 1.6 en même temps que le support E4X :

 for each (var lang in langages.lang) {
     alert(lang);
 }

for each...in peut également être utilisée avec des objets JavaScript normaux pour parcourir les valeurs (par opposition aux clés) contenues dans l'objet. Comme avec for...in, il est fortement déconseillé de l'utiliser avec des tableaux.

Il est possible de créer une XMLList à l'aide de la syntaxe XML littérale sans avoir à créer un document XML bien formé, de la manière suivante :

 var xmllist = <>
   <lang>JavaScript</lang>
   <lang>Python</lang>
 </>;

L'opérateur += peut être utilisé pour ajouter des éléments à une XMLList au sein d'un document:

 langages.lang += <lang>Ruby</lang>;

Notez que contrairement aux listes de nœuds renvoyées par les méthodes DOM classiques, les XMLLists sont statiques et ne sont pas mises à jour automatiquement pour refléter les changements dans le DOM. Si vous créez une XMLList comme un sous-ensemble d'un objet XML existant et modifiez ensuite l'objet XML original, la XMLList ne reflètera pas ces changements ; il vous faudra la recréer pour avoir les mises à jour les plus récentes :

 var langages = <langages>
   <lang>JavaScript</lang>
   <lang>Python</lang>
 </langages>;
 
 var lang = langages.lang;
 alert(lang.length()); // Affiche 2
 
 langages.lang += <lang>Ruby</lang>;
 alert(lang.length()); // Affiche toujours 2
 
 lang = langages.lang; // Recrée la XMLList
 alert(lang.length()); // Affiche 3

Recherche et filtrage

E4X fournit des opérateurs spéciaux pour sélectionner des nœuds dans un document qui correspondent à des critères spécifiques. Ces opérations de filtrage sont spécifiées à l'aide d'une expression contenue entre parenthèses :

var html = <html>
  <p id="p1">Premier paragraphe</p>
  <p id="p2">Second paragraphe</p>
</html>;

alert(html.p.(@id == "p1")); // Affiche "Premier paragraphe"

Les nœuds correspondant au chemin avant l'expression (dans ce cas les éléments paragraphe) sont ajoutées à la chaîne de visibilité avant l'évaluation de l'expression, comme s'ils avaient été spécifiés avec l'instruction with.

Par conséquents, des filtres peuvent également être utilisés pour la valeur d'un seul nœud contenu dans l'élément courant :

var gens = <gens>
  <personne>
    <nom>Pierre</nom>
    <age>32</age>
  </personne>
  <personne>
    <nom>Paul</nom>
    <age>46</age>
  </personne>
</gens>;

alert(gens.personne.(nom == "Paul").age); // Affiche 46

Les expressions de filtres peuvent même utiliser des fonctions JavaScript :

function plusde40(i) {
    return i > 40;
}

alert(gens.personne.(plusde40(parseInt(age))).nom); // Affiche Paul

Gestion des espaces de noms

E4X gère entièrement les espaces de noms. Tout objet XML représentant un nœud ou un attribut fournit une méthode name() renvoyant un objet QName, qui permet d'inspecter facilement les éléments avec un espace de noms.

Défini par défaut

default xml namespace = "https://www.w3.org/1999/xhtml";
// Il n'est plus nécessaire de spécifier l'espace de noms dans la balise html
var xhtml = <html><head><title></title></head><body>
            <p>text</p></body></html>;
alert(xhtml.head);

Défini "manuellement"

var xhtml = <html xmlns="https://www.w3.org/1999/xhtml">
	<head>
		<title>Démo de SVG intégré</title>
	</head>
	<body>
		<h1>Démo de SVG intégré</h1>
		<svg xmlns="https://www.w3.org/2000/svg" 
			viewBox="0 0 100 100">
			<circle cx="50"
				cy="50"
				r="20"
				stroke="orange"
				stroke-width="2px"
				fill="yellow" />
		</svg>
	</body>
</html>;

alert(xhtml.name().localName); // Affiche "html"
alert(xhtml.name().uri); // Affiche "https://www.w3.org/1999/xhtml"

Pour accéder à des éléments qui sont au sein d'un espace de noms pas défini par défaut, créez d'abord un objet Namespace encapsulant l'URI pour cet espace de noms :

var svgns = new Namespace('https://www.w3.org/2000/svg');

Celui-ci peut alors être utilisé dans des requêtes E4X en utilisant namespace::localName au lieu d'un nom d'élément normal :

var svg = xhtml..svgns::svg;
alert(svg); // Affiche la portion <svg> du document

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : teoli, matteodelabre, Mgjbot, BenoitL
 Dernière mise à jour par : teoli,