1. Устанавливайте resultFormat="e4x" для HTTPService
По умолчанию, resultFormat для <mx:HTTPService> является "object". Но при получении XML данных, "object" - это не то, что вам нужно. Если же задать "e4x", то lastResult будет являтся XML объектом, который можно парсить с помощью E4X выражений.
2. E4X выражения не ссылаются на самый верхний тег XML
Итак, имеем <mx:HTTPService>, названный myService с resultFormat="e4x", возвращающим следующую структуру:
<?xml version="1.0"?>
<people>
<person>mike</person>
<person>sho</person>
<person>nj</person>
</people>
Эти данные содержатся в myService.lastResult (или в event.result.) Как получить XMLList всех элементов <person>?
Часто думают, что E4X выражения составляют от корневого тега <people>:
var personNodes:XMLList = myService.lastResult.people.person;
// неправильно
А правильно так :
var personNodes:XMLList = myService.lastResult.person;
// правильно
3. Используйте for each, а не for
ECMAScript давно имеет структуру for (ключ в коллекции). Но обратите внимание, что при использовании этого выражения переменной цикла является ключ коллекции, а не значение текущего элемента, поэтому в цикле необходимо писать коллекция[ключ] для ображения к его значению.
E4X добавляет следующую структуру (которую можно использовать на любой коллекции): for each (значение в коллекции). Рассмотрим примеры:
for (var key:* in myService.lastResult.person) {
var value:* = myService.lastResult.person[key];
...
}
А теперь for each:
for each (var value:* in myService.lastResult.person)
{... }
4. Используйте for each (child in parent.*), вместо for each (child in parent)
Итак, есть документ :
var mydocument:XML =Теперь необходимо перебрать всех мышей у этого кота.
<root>
<cat>
<mouse />
<mouse />
<mouse />
</cat>
</root>
var cats:XMLList = mydocument.cat; // это только один элемент
var o:Object = ...; for each (var property:* in o) ...Вы думаете, что следующим образом вы делаете тоже самое:
for each (var mouse:XML in cats) ... // неправильно
Увы, E4X отличается. В E4X, "cats" - это коллекция -- список узлов <cat>, а в примере есть только один <cat>.
Поэтому, чтобы перебрать всех мышей необходимо использовать следующую структуру:// перебрать все прямые дочерние элементы
for each (var mouse:XML in cats.*) { ... }
// или перебрать всех прямых потомков, которые являются узлами <mouse>
for each (var mouse:XML in cats.mouse) { ... }
5. E4X специально стирает различия между XML и XMLList
При изучении E4X, вы узнаете, что есть два типа данных: XML и XMLList. Вроде легко, но потом появляются проблемы с неправильной типизацией данных.var mydocument =
<root>
<rabbit name="Brownster Johansson McGee" />
</root>;
// 'mydocument.rabbit' - список всех узлов <rabbit>, значит
// myPetRabbit должен быть XMLList? Но я назвал переменную
// 'myPetRabbit', а не 'myPetRabbits',
// потому что я знаю, что заяц только один.
var myPetRabbit:XMLList = mydocument.rabbit;
// Как же его зовут? Почему следующее выражение не вызывает ошибки,
//ведь myPetRabbit - это XMLList?
trace(myPetRabbit.@name);
Причина в том, что E4X намеренно стирает различия между XML и XMLList. Каждый XMLList, который содержит один элемент, будет рассматриваться как XML. (Если 'myPetRabbit' будет содержать несколько узлов, то myPetRabbit.@name будет возвращать список всех атрибутов "name" все узлов <rabbit>.)
Например, рассмотрим документацию по методу XMLList.toString():
- Если объект XML имеет простую структуру, то метод toString() возвращает содержимое узлов без тегов, атрибутов, пространств имен и т.п.
- Если объект XML имеет сложную структуру, то метод toString() возвращает все содержимое, вклюяая теги, атрибуты и т.п.
То есть если XMLList содержит <node>hello</node>, то toString() вернет "hello"; но если он содержит <node>hello</node><node>goodbye</node>, toString() вернет "<node>hello</node><node>goodbye</node>" (а не "hellogoodbye"). Если же вам всегда нужен полный XML, используйте toXMLString() вместо of toString().
6. Внимание! Простое выражение может вам дорого обойтись
При использовании простых объектов нет ничего удивительного в использовании следующего кода:
var x:Object = ...;
if (x.y.z == 3)
foo(x.y.z);
Код работает быстро, проблем не вознкает.
Но в E4X операция типа "x.y.z" будет означать, что цикл проходит через всю XML-структуру и ищет соответствующие совпадения:
var mydocument:XML = ...;
if (mydocument.cat.mouse.length() == 3)
{foo(mydocument.cat.mouse)};
Итак, если вам потом понадобиться использовать результат, то лучше сохранить его в XMLLis переменнойt:
var mydocument:XML = ...;
var mice:XMLList = mydocument.cat.mouse;
if (mice.length() == 3)
{foo(mice);}
7. Используйте дебаггер
Отладчик поможет вам разобраться в значениях XML и XMLList переменных.
Отсюда
2 комментария:
спасибо, хоть какая-то ясность появилась, а то в Flex2 Developers Guide про e4x практически нефига нет
полезная статья http://xpoint.ru/know-how/JavaScript/E4X
правда для JS, но e4x и в африке e4x.
Отправить комментарий