Parcours de structures XML

Flash Player 9 et les versions ultérieures, Adobe AIR 1.0 et les versions ultérieures

L’une des fonctions puissantes d’XML est sa capacité à fournir des données imbriquées, complexes, via une chaîne linéaire de caractères de texte. Lorsque vous chargez des données dans un objet XML, ActionScript les analyse et charge sa structure hiérarchique en mémoire (ou envoie une erreur d’exécution si les données XML ne sont pas formées correctement).

Les opérateurs et les méthodes des objets XML et XMLList permettent de parcourir aisément la structure des données XML.

Utilisez l’opérateur point (.) et l’opérateur d’accesseur descendant (..) pour accéder aux propriétés enfant d’un objet XML. Considérez l’objet XML suivant :

var myXML:XML =  
    <order> 
        <book ISBN="0942407296"> 
            <title>Baking Extravagant Pastries with Kumquats</title> 
            <author> 
                <lastName>Contino</lastName> 
                <firstName>Chuck</firstName> 
            </author> 
            <pageCount>238</pageCount> 
        </book> 
        <book ISBN="0865436401"> 
            <title>Emu Care and Breeding</title> 
            <editor> 
                <lastName>Case</lastName> 
                <firstName>Justin</firstName> 
            </editor> 
            <pageCount>115</pageCount> 
        </book> 
    </order>

L’objet myXML.book est un objet XMLList contenant des propriétés enfant de l’objet myXML appelées book . Ces deux objets XML correspondent aux deux propriétés book de l’objet myXML .

L’objet myXML..lastName est un objet XMLList contenant des propriétés descendantes appelées lastName . Ces deux objets XML correspondent aux deux propriétés lastName de l’objet myXML .

L’objet myXML.book.editor.lastName est un objet XMLList contenant tout enfant appelé lastName des enfants appelés editor des enfants appelés book de l’objet myXML : en l’occurrence, un objet XMLList contenant un seul objet XML (la propriété lastName dont la valeur correspond à « Case »).

Accès aux nœuds enfant et parent

La méthode parent() renvoie le parent d’un objet XML.

Vous pouvez utiliser les valeurs d’index ordinales d’une liste enfant pour accéder à des objets enfant spécifiques. Par exemple, considérez un objet XML myXML ayant deux propriétés enfant appelées book . Chaque propriété enfant appelée book possède un numéro d’index qui lui est associé :

myXML.book[0] 
myXML.book[1]

Pour accéder à un petit-enfant spécifique, vous pouvez indiquer des numéros d’index pour les noms de l’enfant et du petit-enfant :

myXML.book[0].title[0]

Cependant, s’il n’existe qu’un seul enfant de x.book[0] nommé title , vous pouvez omettre la référence d’index, comme suit :

myXML.book[0].title

De même, s’il n’existe qu’un seul enfant book de l’objet x et que cet objet enfant possède un seul objet title, vous pouvez omettre les deux références d’index, de la façon suivante :

myXML.book.title

Vous pouvez utiliser la méthode child() pour accéder à des enfants dont le nom est basé sur une variable ou une expression, comme indiqué dans l’exemple suivant :

var myXML:XML =  
        <order> 
            <book> 
                <title>Dictionary</title> 
            </book> 
        </order>; 
 
var childName:String = "book"; 
 
trace(myXML.child(childName).title) // output: Dictionary

Accès à des attributs

Utilisez le symbole @ (l’opérateur identifiant d’attribut) pour accéder aux attributs dans un objet XML ou XMLList, comme indiqué dans le code suivant :

var employee:XML =  
    <employee id="6401" code="233"> 
        <lastName>Wu</lastName> 
        <firstName>Erin</firstName> 
    </employee>; 
trace(employee.@id); // 6401

Vous pouvez utiliser le symbole de caractère générique * avec le symbole @ pour accéder à tous les attributs d’un objet XML ou XMLList, comme dans le code suivant :

var employee:XML =  
    <employee id="6401" code="233"> 
        <lastName>Wu</lastName> 
        <firstName>Erin</firstName> 
    </employee>; 
trace(employee.@*.toXMLString());  
// 6401 
// 233

Vous pouvez utiliser la méthode attribute() ou attributes() pour accéder à un attribut spécifique ou à tous les attributs d’un objet XML ou XMLList, comme dans le code suivant :

var employee:XML =  
    <employee id="6401" code="233"> 
        <lastName>Wu</lastName> 
        <firstName>Erin</firstName> 
    </employee>; 
trace(employee.attribute("id")); // 6401 
trace(employee.attribute("*").toXMLString());  
// 6401 
// 233 
trace(employee.attributes().toXMLString());  
// 6401 
// 233

Vous pouvez également utiliser la syntaxe suivante pour accéder à des attributs, comme indiqué dans l’exemple suivant :

employee.attribute("id") 
employee["@id"] 
employee.@["id"]

Ils sont tous équivalents à employee.@id . Cependant, la syntaxe employee.@id est préférable.

Filtrage par attribut ou valeur d’élément

Vous pouvez utiliser les opérateurs parenthèses— ( et ) —pour filtrer des éléments avec un nom d’élément spécifique ou une valeur d’attribut. Considérez l’objet XML suivant :

var x:XML =  
    <employeeList> 
        <employee id="347"> 
            <lastName>Zmed</lastName> 
            <firstName>Sue</firstName> 
            <position>Data analyst</position> 
        </employee> 
        <employee id="348"> 
            <lastName>McGee</lastName> 
            <firstName>Chuck</firstName> 
            <position>Jr. data analyst</position> 
        </employee> 
    </employeeList>

Les expressions suivantes sont toutes valides :

  • x.employee.(lastName == "McGee") —Il s’agit du deuxième nœud employee .

  • x.employee.(lastName == "McGee").firstName —Il s’agit de la propriété firstName du deuxième nœud employee .

  • x.employee.(lastName == "McGee").@id —Il s’agit de la valeur de l’attribut id du deuxième nœud employee .

  • x.employee.(@id == 347) —Le premier nœud employee .

  • x.employee.(@id == 347).lastName —Il s’agit de la propriété lastName du premier nœud employee .

  • x.employee.(@id > 300) —Il s’agit d’un XMLList avec deux propriétés employee .

  • x.employee.(position.toString().search("analyst") > -1) —Il s’agit d’un XMLList avec deux propriétés position .

Si vous tentez d’appliquer un filtre à des attributs ou des éléments qui n’existent pas, une exception est renvoyée. Par exemple, la dernière ligne du code suivant génère une erreur car il n’existe aucun attribut id dans le deuxième élément p :

var doc:XML =  
            <body> 
                <p id='123'>Hello, <b>Bob</b>.</p> 
                <p>Hello.</p> 
            </body>; 
trace(doc.p.(@id == '123'));

De même, la dernière ligne du code suivant génère une erreur car il n’existe aucune propriété b du deuxième élément p :

var doc:XML =  
            <body> 
                <p id='123'>Hello, <b>Bob</b>.</p> 
                <p>Hello.</p> 
            </body>; 
trace(doc.p.(b == 'Bob'));

Pour éviter ces erreurs, vous pouvez identifier les propriétés ayant les éléments ou les attributs correspondants, à l’aide des méthodes attribute() et elements() , comme dans le code suivant :

var doc:XML =  
            <body> 
                <p id='123'>Hello, <b>Bob</b>.</p> 
                <p>Hello.</p> 
            </body>; 
trace(doc.p.(attribute('id') == '123')); 
trace(doc.p.(elements('b') == 'Bob'));

Vous pouvez également utiliser la méthode hasOwnProperty() , comme dans le code suivant :

var doc:XML =  
            <body> 
                <p id='123'>Hello, <b>Bob</b>.</p> 
                <p>Hello.</p> 
            </body>; 
trace(doc.p.(hasOwnProperty('@id') && @id == '123')); 
trace(doc.p.(hasOwnProperty('b') && b == 'Bob'));

Utilisation de for..in et for each.. dans les instructions

ActionScript 3.0 propose les instructions for..in et for each..in pour permettre les itérations dans les objets XMLList. Par exemple, considérez l’objet XML suivant, myXML , et l’objet XMLList, myXML.item . L’objet XMLList, myXML.item, est constitué de deux nœuds item de l’objet XML.

var myXML:XML =  
    <order> 
        <item id='1' quantity='2'> 
            <menuName>burger</menuName> 
            <price>3.95</price> 
        </item> 
        <item id='2' quantity='2'> 
            <menuName>fries</menuName> 
            <price>1.45</price> 
        </item> 
    </order>;

La boucle for..in permet de procéder à une itération sur un ensemble de noms de propriété dans un objet XMLList :

var total:Number = 0; 
for (var pname:String in myXML.item) 
{ 
    total += myXML.item.@quantity[pname] * myXML.item.price[pname]; 
}

La boucle for each..in permet de procéder à une itération dans les propriétés de l’objet XMLList :

var total2:Number = 0; 
for each (var prop:XML in myXML.item) 
{ 
    total2 += prop.@quantity * prop.price; 
}