4

我正在进行的一个项目将从网络服务器中提取 XML 并从中构建数据存储。数据将具有某些核心字段,但需要可扩展......例如,我有一个,以后可能想要添加额外的字段。

在 Flex 应用程序中,我不希望中央数据存储处理 XML 对象或只是将属性放入对象中。我想要有强类型,例如 Person 类,它是从 XML 创建/填充的。

如何以灵活的方式做到这一点?如果属性名称匹配,Flex 是否能够从 XML 自动构建 Person,或者我是否需要为 、 等编写转换功能?

4

6 回答 6

3

我不认为这可以自动完成。我通常创建一个类来镜像我拥有的​​ 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]);
       }
    }
  }
于 2008-10-09T12:13:52.913 回答
1

如果您不依赖于 XML(例如,您有一个应用服务器而不是文件服务器),您可以考虑使用 AMF(动作消息格式)来传输数据。有一些项目将 AMF 暴露给服务器,包括 Adob​​e 自己的Blaze DS和社区开源变体,如OpenAMFAMFPHPPyAMF等。这将使您能够将自定义对象从服务器传输到 Flex,自动解析数据类型和类型安全。看看这个数据传输选项的比较,以了解相对优点。

话虽如此,XML 对于应用程序配置数据之类的东西非常有用,并且在这些情况下,您没有运行应用程序服务器。我同意另一张海报,我将立即手动将 xml 解析为适当的结构。我通常将这些与修复后的 VO(用于值对象)一起存储,并将成员保留为公开。我经常分层地做这件事。

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));
                }
            }
        }
    }
}
于 2008-10-11T19:49:36.337 回答
0

使用 flex simplexmldecoder 类@flexExamples将 xml 转换为对象

于 2008-10-24T11:11:18.807 回答
0

不久前,我开始研究一个 Flex 库,该库将帮助序列化和反序列化动作脚本对象与 XML 之间的关系。您所要做的就是创建模型对象,在字段上添加一些注释,让序列化程序知道您希望如何序列化字段(元素、属性、名称等)并调用(反)序列化过程。

我认为它适合您的需求。

如果您愿意,可以在http://code.google.com/p/flexxb/上查看。

希望这将被证明是有帮助的。

于 2008-11-11T12:13:59.537 回答
0

创建强数据类型有几个优点,代码完成和编译时语法检查是最重要的。可以完成手动映射,但应该生成(因此毕竟不再是真正的手动映射)以避免迟早不同步。

基于自省的通用转换库是通用的、易于使用的,并且应该足以满足大多数用例。

JAXB 是 Java 的标准。ASXB为 Actionscript 世界提供了这个想法的轻量级实现。它使用带有注释的显式 AS 对象来(取消)编组对象和 XML。

如果您被迫在线上使用 XML,我建议您仔细看看 ASXB。如果您可以自由选择格式并拥有支持的服务器端,那么 Adob​​e 自己的 AMF 格式应该是您的选择,因为它在语言中直接受支持,并且在传输过程中的开销要低得多。

在我们当前的项目中,我们编写了小型代码生成器,它采用 Java 端的外部 API(源自省,也复制 Javadoc)并在我们的构建过程中从中生成 AS 类。因此,当外部需求迫使我们这样做时,从 AMF 切换到 XML 很容易。

PS:记得将编译器参数添加到您的 flex 配置文件中以保留注释

于 2009-07-13T13:11:16.017 回答
0

AsBeanGen可以做到这一点。它为 DTD 驱动的 XML 文件生成值对象。

于 2009-09-02T22:39:15.233 回答