Парсинг XML в ActionScript 3.0
Возникла у меня однажды задача – создать Flash-контрол, в котором постоянно сверху вниз прокручивается список неких сайтов, причем при наведении мыши на этот контрол прокручивание останавливается, а содержимое пункта списка, на который наведена мышь, разворачивается, и мы теперь можем наблюдать саму ссылку на сайт и краткое описание сайта внизу. Как-то так:
Собственно, хотелось создать универсальный контрол, такой, чтобы и список сайтов и все цвета, и скорость прокрутки, и вообще все изменяемые параметры хранились бы где-то отдельно от самого Flash-контрола, чтобы, когда дизайнеру захочется поменять оформление этого котнрола или его содержимое, он бы меня не дергал лишний раз. Разумное желание. И решил я остановиться на хранении всех этих данных в XML-файле.
Файл этот имеет вот такой формат:
<?xml version="1.0" encoding="UTF-8"?> <config> <control speed="10" indent="24.9"/> <sites> <site name="веб-разработка" link="easy4web.ru" url="http://easy4web.ru/" descr="веб-дизайнер и веб-программист срывают оковы, освещают темные места" height="38"/> <site name="Яндекс" link="yandex.ru" url="http://yandex.ru/" descr=" Поиск от Яндекс. Найдется все!" height="38"/> <site name="почта от google" link="gmail.com" url="http://gmail.com/" descr="Бесплатная почта от google. Попробуй, не пожалеешь." height="38"/> </sites> </config>
Здесь мы видим один корневой элемент <config> в который вложены: элемент <control> одержащий в себе атрибуты, касающиеся всего контрола в целом, и элемент <sites> содержащий в себе дочерние узлы <site>, каждый из которых описывает отдельный элемент прокручиваемого в контроле списка.
Осталось теперь разобраться как разобрать этот файл при помощи ActionScript.
Но для начала структурируем немного в виде классов информацию, хранящуюся в XML-файле.
Элемент <site> мы опишем следующим классом (файл SiteItem.as):
package inc{
public class SiteItem extends Object {
public var pName:String;
public var pLink:String;
public var pURL:String;
public var pDescr:String;
public var pHeight:Number;
public function SiteItem(p_Name:String, p_Link:String, p_URL:String,
p_Descr:String, p_Height:Number){
pName=p_Name;
pLink=p_Link;
pURL=p_URL;
pDescr=p_Descr;
pHeight=p_Height;
}
}
}
Как видно, это просто класс с открытыми полями и одним конструктором. Ничего сложного.
А вот еще один класс, описывающий весь XML-файл (ScrollerParameters.as):
package inc{
public class ScrollerParameters extends Object{
public var list:Array;
public var indent:Number;
public var speed:Number;
public function ScrollerParameters(){
list=new Array();
}
}
}
Здесь также есть набор открытых полей и конструктор.
А вот и сам скрипт разбора XML-данных (scrollrequest.as).
package inc{
import flash.display.MovieClip;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.events.*;
import flash.net.URLLoaderDataFormat;
public class scrollrequest extends MovieClip {
private var xml:XML;
public var parameters:ScrollerParameters=new ScrollerParameters();
public function scrollrequest(url:String) {
var loader:URLLoader=new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, loadXML);
loader.load(new URLRequest(url));
}
private function loadXML(e:Event):void
{
try {
xml=new XML(e.target.data);
parseXML();
}
catch(e:TypeError) {
trace( "Could not parse text into XML" );
trace( e.message );
}
}
private function parseXML(){
var control:XML=xml["control"][0];
parameters.speed=control.attribute("speed");
parameters.indent=control.attribute("indent");
var sites:XMLList=xml["sites"][0].child("site");
for(var i:Number=0; i<sites.length(); i++){
var site=sites[i];
var s=new SiteItem(site.attribute("name"), site.attribute("link"),
site.attribute("url"), site.attribute("descr"),
site.attribute("height"));
parameters.list.push(s);
}
notifyListeners("LOAD");
}
private function notifyListeners(ev:String) {
var e:Event = new Event(ev, false, false);
dispatchEvent(e);
}
}
}
Как можно заметить, загрузка XML-файла происходит в конструкторе класса scrollrequest, в принципе, загрузку файла я использую лишь один раз в жизненном цикле этого класса, а потому не стал делать отдельный метод для загрузки файла с сервера.
Для загрузки XML-файла с сервера используется стандартная схема загрузки при помощи класса URLLoader.
Обработчик loadXML срабатывает после полной загрузки файла с сервера и вызывает метод parseXML(), который, собственно, и осуществляет разбор XML-Данных.
Чтобы получить список всех узлов с именем control мы используем оператор “квадратные скобки – “xml["control"], а чтобы получить единственный узел с таким именем нужмно использовать кщк один оператор “квадратные скобки”, чтобы обратиться к первому и единственному элементу в списке узлов. То есть вот так xml["control"][0].
Обращение к конкртеному атрибуту узла происходит посредством метода attribute(’par’), которому в качестве параметра передается имя атрибута.
Чтобы получить список всех дочерних элементов узла, применяется метод child(’par’), которому в качестве параметра передается имя дочерних узлов, которые мы хотим увидеть в списке. То есть вот так xml["sites"][0].child(”site”) мы получим массив всех эелементов <site> у которых родителем является элемент <site>.
Пробег по всем элементам списка осущетсвляется обычным циклом for.
Вот и все, что я хотел сегодня рассказать.
Прочтите еще:


