Парсинг XML в ActionScript 3.0

Вячеслав Гринин, June 21, 2009

Возникла у меня однажды задача – создать Flash-контрол, в котором постоянно сверху вниз прокручивается список неких сайтов, причем при наведении мыши на этот контрол прокручивание останавливается, а содержимое пункта списка, на который наведена мышь, разворачивается, и мы теперь можем наблюдать саму ссылку на сайт и краткое описание сайта внизу. Как-то так:

scroller

Собственно, хотелось создать универсальный контрол, такой, чтобы и список сайтов и все цвета, и скорость прокрутки, и вообще все изменяемые параметры хранились бы где-то отдельно от самого Flash-контрола, чтобы, когда дизайнеру захочется поменять оформление этого котнрола или его содержимое, он бы меня не дергал лишний раз. Разумное желание. И решил я остановиться на хранении всех этих данных в XML-файле.

Файл этот имеет вот такой формат:

<?xml version="1.0" encoding="UTF-8"?>
<config>
<control speed="10" indent="24.9"/>
<sites>
<site name="веб-разработка" link="easy-4-web.ru" 
url="http://easy-4-web.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.

Вот и все, что я хотел сегодня рассказать.

Поиск по блогу:
Подписаться:
Популярные:
Облако тегов:
Разное:
Счетчик: