Search
Write a publication
Pull to refresh

XML-классы в ActionScript (Adobe Flex)

Когда я только начинал работать с Flex, одной из первых задач была загрузка XML-документа по HTTP-протоколу.
Для работы с HTTP в ActionScript этого предназначен класс HTTPService, в котором одним из основных оказалось загадочное (для меня тогда) свойство resultFormat, которое и определяло формат загруженных данных.

Вот как в документации описаны возможные значения этого свойства:
  • object Данные загружаются как XML и преобразуется в дерево объектов ActionScript.
  • array Данные загружаются как XML и преобразуется в дерево объектов ActionScript, которое загружается в массив
  • xml Данные загружаются как XML и преобразуется в XML как объект типа XMLNode.
  • flashvars Данные загружаются в виде пар name=value, разделенных амперсандом, и преобразуется в объект ActionScript.
  • text Данные загружаются как текст, без преобразования.
  • e4x Данные загружаются как XML и преобразуются в тип ActionScript XML, который можно обрабатывать при помощи E4X (EcmaScript for XML).

XML упоминается в четырех вариантах из шести, причем как явные xml-типы упоминаются два — XMLNode и XML. Какой следует выбрать?

Правильный ответ (скажем так, не правильный, а в большинстве случаев оптимальный) — это e4x, а совсем не xml, как можно было подумать (и как, кстати, я и решил сначала).

Связано это с тем, что в ActionScript/Flex существует два подхода к работе с XML-данными: один — используя классы из пакета flash.xml (именно данные такого типа и вернет HTTPService, если указать 'xml' в свойстве resultFormat), второй — используя встроенные (начиная с ActionScript 3.0) классы XML и связанный с ним класс XMLList (а для такой работы надо указать e4x).

Дополнительной путаницы добавляет то, что в ActionScript 2.0 класс XMLNode назывался XML, а в 3.0 его переименовали, а XML – это уже совершеннго другой класс.
Классы XMLDocument, XMLNode, XMLType в ActionScript 3.0 оставлены для обратной совместимости с версией 2.0 языка (довольно странная обратная совместимость, кстати — с переименованием типов). Классы реализуют стандартный механизм DOM, то есть все элементы XMLNode имеют стандартные методы наподобие appendChild, childNodes, nodeName, nodeType и т.д.

Значительно более удобен механизм E4X (EcmaScript for XML), появившийся в новой версии ActionScript 3.0. Данный интерфейс реализуют классы XML и связанный с ним XMLList.

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

var x:XML = value of tag
;

или непосредственно передать XML в функцию:

function process(what:XML):void
….
process(text);

Обращаю внимание, что XML передается не как строки (String), а именно как XML-данные.

Еще одним огромным преимуществом является уже упомянутый E4X, который позволяет реализовывать весьма сложные выборки из XML-данных довольно простыми запросами.

Для примера сравним работу с одними и теми же данными (данные взяты из ActionScript language reference) при использовании XMLNode/XMLDocument и XML.
Вот данные, которые мы обрабатываем:

/>
/>
/>
/>
/>
/>


Предположим, нам надо извлечь из него все названия книг (аттрибут name тэга book) и поместить в массив list.
Вот реализация данного с использованием XMLNode и XMLDocument:

var x:XMLDocument = new XMLDocument;
x.parseXML(''+
'/>'+
'/>'+
'/>'+
'/>'+
'/>'+
'/>'+
'');
var list:Array = new Array;
for each(var s:XMLNode in x.childNodes[0].childNodes)
{
list.push(s.attributes.name);
}


Неудобства: 1)XML загружается как строка и потом парсится. Дополнительное время на обработку (конечно, не всегда актуально — в большинстве случаев XML-документ и так разбирается из полученной откуда-то строки), общее неудобство; 2)используются громоздкие конструкции типа .childNodes[0].childNodes. Здесь задача довольно простая, но легко представить, в какие монстрообразные конструкции это может развиться в случае более-менее сложных разветвленных данных.

Теперь реализаци того же на XML/ XMLList:

var xml:XML = />
/>
/>
/>
/>
/>
;
var list:Array = new Array;
for each(var bookName:String in xml.book.@name)
{
list.push(bookName);
}

Подход более удобен при программировании: XML задается непосредственно в исходном коде, для доступа к полям используются легкие конструкции E4X. E4X вообще довольно комфортный для работы язык, например, «получить значение аттрибута index для тэга item, у которого атрибут name равен строке s, а тэг является дочерним элементом корня XML-документа», описывается так: xml.item.(@name==s).@index

Исходя из рассмотренного, можно дать рекомендацию начинающим Flex-программистам: основное правило при работе с XML в ActionScript – это избегать использования классов XMLNode, XMLDocument и вообще пакета flash.xml (достаточно помнить о том, что это классы, оставленные для обратной совместимости с ActionScript 2.0) и изучить E4X, благо он используется не только в ActionScript, но и в других популярных проектах (http://en.wikipedia.org/wiki/ECMAScript_for_XML).

Список использованных ресурсов:
1. Adobe Language Reference
2. EcmaScript for XML
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.