Преобразование данных XML в сильный тип Flex - PullRequest
4 голосов
/ 09 октября 2008

Проект, над которым я работаю, извлечет XML с веб-сервера и создаст из него хранилище данных. У данных будут определенные основные поля, но они должны быть расширяемыми ... например, у меня есть и более поздние, которые могут иметь дополнительные поля.

В приложении Flex я не хочу, чтобы центральное хранилище данных работало с объектами XML или просто помещало свойства в объекты. Я хочу иметь строгие типы, например класс Person, который создается / заполняется из XML.

Как это можно сделать гибким способом? Может ли Flex автоматически создавать Person из XML, если имена атрибутов совпадают, или мне нужно написать функцию преобразования для и т. Д.?

Ответы [ 6 ]

3 голосов
/ 09 октября 2008

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

package {

  public class Foo{

     public function Foo(barparam1:String, barparam2:uint, barparam3:String, barparam4:Number){
       this._bar1 = barparam1;
       this._bar2 = barparam2;
       this._bar3 = barparam3;
       this._bar4 = barparam4;
       }

     protected var _bar1:String;
     protected var _bar2:uint;
     protected var _bar3:String;
     protected var _bar4:Number;

     public function get bar1():String{ return this._bar1; }
     public function get bar2():uint    { return this._bar2; }
     public function get bar3():String  { return this._bar3; }
     public function get bar4():Number  { return this._bar4; }

     public function toString():String{
        return "[Foo bar1:\"" + this.bar1 + "\", bar3:\"" + this.bar3 + "\", bar2:" + this.bar2 + ", bar4:" + this.bar4 + "]";
        }

     public static function createFromXml(xmlParam:XML):Foo{

        /* XML Format:
          <foo bar1="bar1value" bar2="5">
            <bar3>bar3 data</bar3>
            <bar4>10</bar4>
          </foo>
        */

       return new Foo(xmlParam.@bar1, xmlParam.@bar2, xmlParam.bar3[0], xmlParam.bar4[0]);
       }
    }
  }
1 голос
/ 11 октября 2008

Если вы не привязаны к XML (например, у вас есть сервер приложений вместо файлового сервера), вы можете использовать AMF ( Action Message Format ) для передачи данных. Есть несколько проектов, которые предоставляют AMF для серверов, включая собственные Blaze DS от Adobe и варианты с открытым исходным кодом сообщества, такие как OpenAMF , AMFPHP , PyAMF и так далее. Это даст вам возможность переносить пользовательские объекты с сервера во Flex, автоматический анализ типов данных и безопасность типов. Взгляните на это сравнение вариантов передачи данных , чтобы получить представление об относительных достоинствах.

При этом XML может быть очень полезен для таких вещей, как данные конфигурации приложения, и в тех случаях, когда вы не используете сервер приложений. Я согласен с другим постером, где я сразу же разберу xml в соответствующие структуры вручную. Я обычно сохраняю их с VO после исправления (для Value Object) и оставляю участников как открытые. Я часто делаю это иерархически.

package model.vo
{
public class ConfigVO
{
    public var foo:String;
    public var bar:int;
    public var baz:Boolean;
    public var sections:Array;

    public function ConfigVO(xml:XML)
    {
        parseXML(xml);
    }

    private function parseXML(xml:XML):void
    {
        foo = xml.foo;
        bar = xml.bar;
        baz = (xml.baz == "true");

        sections = [];
        for each(var sectionXML:XML in xml.section)
        {
            sections.push(new SectionVO(sectionXML));
        }
    }
}
}

package model.vo
{
public class SectionVO
{
    public var title:String;

    public function SectionVO(xml:XML)
    {
        parseXML(xml);
    }

    private function parseXML(xml:XML):void
    {
        title = xml.@title;
    }
}
}

В прошлом я видел системы, которые будут связывать имена элементов XML с определениями классов. Они обычно используют своего рода интроспекцию в классе, чтобы определить, какие свойства считывать из XML, или у них будут некоторые статические свойства класса, которые сопоставляют свойства экземпляра с тегами или атрибутами XML. По моему опыту, они гораздо больше проблем, чем они того стоят. Для добавления нового открытого свойства и одной строки для считывания данных из атрибута или дочернего тега требуется всего 2 секунды. Я предлагаю избегать таких сложных схем, но я приведу простой пример для полноты.

package model
{
    public class XMLReader
    {
        // maps <tagname> to a class 
        private static var elementClassMap:Object =
        {
            "section": SectionVO,
            "person": PersonVO
        };

        public var parsedElements:Array;

        public function XMLReader(xml:XML)
        {
            parsedElements = [];
            parseXML(xml);
        }

        private function parseXML(xml:XML):void
        {
            var voClass:Class;
            for each(var element:XML in xml.children())
            {
                voClass = elementClassMap[element.name().localname];
                if(voClass)
                {
                    parsedElements.push(new voClass(element));
                }
            }
        }
    }
}
0 голосов
/ 03 сентября 2009

AsBeanGen может сделать это. Он генерирует объекты значений для управляемых DTD XML-файлов.

0 голосов
/ 13 июля 2009

Создание надежных типов данных имеет несколько преимуществ, наиболее важными из которых являются завершение кода и проверка синтаксиса во время компиляции. Ручные сопоставления могут быть выполнены, но должны быть сгенерированы (и, следовательно, на самом деле больше не являются ручными в конце концов), чтобы избежать несинхронизации рано или поздно.

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

JAXB - это стандарт для Java. ASXB обеспечивает упрощенную реализацию этой идеи для мира Actionscript. Он использует явные объекты AS с аннотациями для (не) маршалирования объектов из и в XML.

Если вы вынуждены использовать XML в сети, я бы посоветовал поближе познакомиться с ASXB. Если вы можете выбирать формат и иметь поддержку на стороне сервера, вам следует выбрать собственный формат AMF Adobes, так как он напрямую поддерживается на языке и имеет гораздо меньшие накладные расходы при транспортировке.

В нашем текущем проекте мы написали небольшие генераторы кода, которые используют внешний API на стороне Java (самоанализ источника, также копировать Javadoc) и генерируют из него классы AS во время нашего процесса сборки. Таким образом, было легко перейти с AMF на XML, когда внешние требования заставили нас сделать это.

PS: не забудьте добавить параметры компилятора в ваш файл конфигурации Flex, чтобы сохранить аннотации

0 голосов
/ 11 ноября 2008

Некоторое время назад я начал работать над библиотекой Flex, которая поможет сериализовать и десериализовать объекты Action Script в и из XML. Все, что вам нужно сделать, это создать объекты вашей модели, поместить некоторые аннотации в поля, чтобы позволить сериализатору узнать, как вы хотите, чтобы поле было сериализовано (элемент, атрибут, какое имя и т. Д.), И вызвать процесс (де) сериализации.

Я думаю, что это соответствует вашим потребностям.

Если вы хотите, вы можете проверить это в http://code.google.com/p/flexxb/.

Надеюсь, это окажется полезным.

0 голосов
/ 24 октября 2008
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...