Пересечение XML-структур

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

Одной из мощных возможностей XML является способность предоставлять через линейную строку текстовых символов сложные, вложенные данные. При загрузке данных в объект XML ActionScript проводит синтаксический анализ данных и загружает в память их иерархическую структуру (или выводит ошибку периода исполнения, если XML-данные плохо сформированы).

Операторы и методы объектов XML и XMLList упрощают задачу пересечения структуры XML-данных.

Используйте оператор точки (.) и оператор доступа к более низкому уровню (..) для получения доступа к свойствам дочернего элемента объекта XML. Рассмотрим следующий объект XML:

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>

Объект myXML.book является объектом XMLList, содержащим свойства дочернего элемента объекта myXML с именем book . Существует два объекта XML, соответствующих двум свойствам book объекта myXML .

Объект myXML..lastName является объектом XMLList, содержащим любое свойство более низкого уровня с именем lastName . Существует два объекта XML, соответствующих двум свойствам lastName объекта myXML .

Объект myXML.book.editor.lastName является объектом XMLList, содержащим любой дочерний элемент с именем lastName дочернего элемента с именем editor дочернего элемента с именем book объекта myXML ; в данном случае объект XMLList содержит только один объект XML (свойство lastName со значением "Case" ).

Получение доступа к родительским и дочерним узлам

Метод parent() возвращает родительский элемент объекта XML.

Для получения доступа к определенным дочерним объектам можно использовать исходные значения указателей списка дочерних элементов. Например, рассмотрим объект XML myXML , имеющий два свойства дочернего элемента с именем book . Каждое свойство дочернего элемента с именем book имеет связанный с ним номер указателя:

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

Чтобы получить доступ к определенному внучатому элементу, можно указать номера указателей для дочернего и внучатого имен:

myXML.book[0].title[0]

Однако при наличии только одного дочернего элемента объекта x.book[0] с именем title можно пропустить ссылку на указатель следующим образом:

myXML.book[0].title

Аналогичным образом при наличии только одного дочернего элемента book объекта x и при условии, что этот дочерний объект имеет только один объект title, можно пропустить ссылки на оба указателя следующим образом:

myXML.book.title

Можно использовать метод child() для перемещения к дочерним элементам с именами на основе переменной или выражения, как это показано в следующем примере:

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

Получение доступа к атрибутам

Используйте символ @ (оператор идентификатора атрибута) для получения доступа к атрибутам объекта XML или XMLList, как показано в следующем коде:

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

Можно использовать групповой символ * с символом @ для получения доступа ко всем атрибутам объекта XML или XMLList, как показано в следующем коде:

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

Можно использовать метод attribute() или attributes() для получения доступа к определенному атрибуту или ко всем атрибутам объекта XML или XMLList, как показано в следующем коде:

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

Обратите внимание, что можно использовать следующий синтаксис для получения доступа к атрибутам, как это показано в следующем примере:

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

Все элементы данного примера эквивалентны employee.@id . Однако синтаксис employee.@id является предпочитаемым подходом.

Фильтрация по значению атрибута или элемента

Можно использовать операторы круглых скобок — ( и ) — для фильтрации элементов по определенному имени элемента или значению атрибута. Рассмотрим следующий объект XML:

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>

Все следующие выражения являются допустимыми:

  • x.employee.(lastName == "McGee") — это второй узел employee .

  • x.employee.(lastName == "McGee").firstName — это свойство firstName второго узла employee .

  • x.employee.(lastName == "McGee").@id — это значение атрибута id второго узла employee .

  • x.employee.(@id == 347) — это первый узел employee .

  • x.employee.(@id == 347).lastName — это свойство lastName первого узла employee .

  • x.employee.(@id > 300) — это объект XMLList с обоими свойствами employee .

  • x.employee.(position.toString().search("analyst") > -1) — это объект XMLList с обоими свойствами position .

Если предпринимается попытка фильтрации несуществующих атрибутов или элементов, создается исключение. Например, последняя строка следующего кода генерирует ошибку, поскольку во втором элементе p отсутствует атрибут id :

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

Аналогичным образом последняя строка следующего кода генерирует ошибку, поскольку во втором элементе p отсутствует свойство b :

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

Чтобы избежать этих ошибок, можно с помощью методов attribute() и elements() обозначить свойства, имеющие совпадающие атрибуты или элементы, как это показано на примере следующего кода:

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'));

Можно также использовать метод hasOwnProperty() , как это показано в следующем коде:

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'));

Использование инструкций for..in и for each..in

ActionScript 3.0 включает инструкции for..in и for each..in , предназначенные для повторения в объектах XMLList. Например, рассмотрим следующий объект XML myXML и объект XMLList myXML.item . Объект XMLList myXML.item состоит из двух узлов item объекта 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>;

Инструкция цикла for..in позволяет осуществлять повторение в наборе имен свойств объекта XMLList:

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

Инструкция цикла for each..in позволяет осуществлять повторение в свойствах объекта XMLList:

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