Как вы заметили, автоматически меняющиеся типы XML и XMLList могут привести к путанице. Такие вещи случаются, когда умные программисты (указывая на Adobe здесь ...) делают удобные обертки вокруг вещей.
То, что происходит, это "автоматическое преобразование типов". И это не останавливается на типе XML. Рассмотрим этот пример XML:
<myXml>
<sound id="0">Boogaloo</sound>
<sound id="1">Bond theme</sound>
<sound id="2">2001</sound>
</myXml>
Допустим, у меня есть вышеуказанный XML в переменной с именем myXml
. В следующем примере E4X возвращает XMLList с одним элементом, и мы получаем доступ к первому элементу XML, используя [0]
:
trace(myXml.sound.(@id == 0)[0] == <sound id="0">Boogaloo</sound>);
// traces true
В этом примере мы пропускаем часть [0]
, полагаясь на автоматическое преобразование типов Flash. Один возвращенный элемент преобразуется в XML:
trace(myXml.sound.(@id == 0) == <sound id="0">Boogaloo</sound>);
// traces true
Но в тех случаях, когда этот соответствующий XML-узел содержит простой текстовый узел, Flash автоматически преобразует тип еще дальше в строку:
trace(myXml.sound.(@id == 0) == "Boogaloo");
// traces true
И если текстовый узел можно интерпретировать как число (узел XML с идентификатором 2), Flash преобразует его даже дальше в число!
trace(myXml.sound.(@id == 2) == 2001);
// traces true
Woot!
Итак, что с этим делать?
Как вы заметили, вы должны быть очень осторожны с типами и «удобной» обработкой XML. Один из рекомендуемых методов - всегда использовать оператор доступа к массиву, чтобы указывать на первый элемент XML результата E4X, когда вы знаете, что хотите получить единственный результат:
config.users.admin[0].settings[0].email.(@type == "work")[0];
Поначалу это выглядит странно и добавляет многословность к коду, но выгода в том, что вы явно говорите, что ищете один admin
элемент, один settings
элемент и один email
элемент типа "work"
. И ты привыкла к этому.
Другой совет - всегда не забывайте приводить к типу, который вы ожидаете использовать. Некоторые примеры:
allUsers = XMLList(config.users);
adminSettings = XML(config.users.admin[0].settings[0]);
adminWorkEmail = String(config.users.admin[0].settings[0].email.(@type == "work")[0]);
adminBirthYear = int(config.users.admin[0].birthdate[0].@year[0]);