LE Blog

Инженер с поэтической душой

02.03.2009 firtree_right Пространства имён XML в ActionScript 3

В последнее время достаточно плотно сталкивался с обработкой XML в ActionScript 3. В третьей версии ActionScript для обработки XML реализована спецификация ECMAScript for XML (E4X). Это значительно упрощает работу. Обращение к дочерним элементам происходит так же, как обращение к свойствам объекта. Об этом я и хочу рассказать в этот раз, взяв для примера что-то более сложное, чем в стандартный примерах.

var xml:XML =
    <robot xmlns="http://robots.org/2069/body/"
              xmlns:color="http://robots.org/2075/bodycolor"
              xmlns:extra="http://extraparts.org/2080/xml"
              xmlns:uni="http://universal.org/2010/robots/xml">
    <body>
      <head>
        <brain uni:id="abc123456" />
        <brain uni:id="abc987654" />
        <casing color:rgb="cfa499" />
      </head>
      <extra:additional name="mono">
        <extra:arm>
          <extra:claw extra:size="12" color:pantone="134f" />
        </extra:arm>
      </extra:additional>
    </body>
    </robot>;

То есть в данном примере присутствует четыре спецификации, которые описывают различные (или возможные) элементы или атрибуты XML. Что же будет, если мы попробуем что-нибудь поискать:

trace(xml.body.length()); // 0

Это произошло потому, что сам XML имеет своё пространство имён (namespace). Поэтому можно сделать так:

trace(xml.body.length()); // 0
var mainNS:Namespace = new Namespace("http://robots.org/2069/body/");
trace(xml.mainNS::body.length()); // 1
default xml namespace = mainNS;
trace(xml.body.length()); // 1

Остальные пространства имён:

var colorNS:Namespace = new Namespace("color", "http://robots.org/2075/bodycolor");
var extraNS:Namespace = new Namespace("extra", "http://extraparts.org/2080/xml");
var uniNS:Namespace = new Namespace("uni", "http://universal.org/2010/robots/xml");

Объект, возвращаемый при выборке имеет тип XMLList. Но не смотря на это, дальнейшую выборку можно продолжать. Так же для примера рассмотрим обращение к атрибутам:

trace(xml.body.head.casing.@colorNS::rgb); // cfa499

В случае, когда элементы не в единственном числе и для большей строгости то же самое можно записать следующим образом.

trace(xml.body[0].head[0].casing[0].@colorNS::rgb[0]); // cfa499

Кстати, обращение к атрибуту так же возвращает XMLList. Поиск по атрибуту, если нам не особо важна структура, будет выглядеть следующим образом:

trace(xml..mainNS::brain.(@uniNS::id.indexOf("abc") >= 0).@uniNS::id.toXMLString());
            //abc123456
            //abc987654

То есть после первой выборки по частичному вхождению id вышло два элемента. Когда мы запросили атрибут, оказалось два атрибута. То есть строгое выражение, если нам нужет второй элемент, будет такое:

trace(xml..mainNS::brain.(@uniNS::id.indexOf("abc") >= 0)[1].@uniNS::id);
            //abc987654

Естественно, что XMLList может быть использован для образования цикла с помощью for .. in.

Ещё один способ обращаться к элементам и атрибутам — это с помощью методов класса XML и объекта QName. Это прекрасный способ, если не нужно «хардкодить» имена элементов. Ещё это может пригодиться, если элементы xml имеют имена, совпадающие со служебными или ключевыми словами ActionScript.

var claw:QName = new QName(extraNS, "claw");
var pantone:QName = new QName(colorNS, "pantone");
trace(xml.descendants(claw)[0].attribute(pantone)); // 134f

Материалы для изучения

Документация класса XML со ссылками Руководство пользователя на тему XML в ActionScript 3 Для хардкорных читателей