将XML数据转换为强Flex类型

时间:2020-12-26 16:33:26

A project I'm working on will pull XML from a web-server and build a data store from it. The data will have certain core fields but needs to be extendable... for example I have a and later might want to have which adds extra fields.

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

In the Flex app, I don't want the central data store to be working on XML objects or simply putting the properties into Objects. I want to have strong types, e.g a Person class, which are created/populated from the XML.

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

How can this be done in a flexible way? Is Flex able to automatically build a Person from an XML if the attribute names match, or do I need to write conversion functionality for , , etc?

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

6 个解决方案

#1


3  

I don't think this can be done automatically. I generally create the a class to mirror the XML structure I have and then create a static class method to create an instance of the object given an XML node. For example:

我不认为这可以自动完成。我通常创建一个类来镜像我的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]);
       }
    }
  }

#2


1  

If you aren't tied to XML (e.g. you have an app server instead of a file server) you could consider using AMF (Action Message Format) to transfer the data. There are a few projects that expose AMF to servers including Adobe's own Blaze DS and community open source variants such as OpenAMF, AMFPHP, PyAMF and so on. This will give you the ability to transfer custom objects from the server to Flex, automatic parsing of data-types and type safety. Have a look at this comparison of data transfer options to get an idea of the relative merits.

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

That being said, XML can be very useful for things like app configuration data and in those instances you aren't running an app server. I agree with the other poster where I will immediately parse the xml into appropriate structures by hand. I usually store these with the post-fix VO (for Value Object) and I leave the members as public. I often do this hierarchically.

话虽这么说,XML对于应用程序配置数据以及那些没有运行应用程序服务器的实例非常有用。我同意另一张海报,我会立即用手将xml解析成适当的结构。我通常使用修复后的VO(对于Value Object)存储它们,并将成员保留为public。我经常分层次地这样做。

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;
    }
}
}

I've seen systems in the past that will bind XML element names to class definitions. These usually use some sort of introspection on the class to determine what properties to read off the xml or they will have some static class properties that map instance properties to xml tags or attributes. In my experience they are much more trouble than they are worth. It takes all of 2 seconds to add a new public property and a single line to read the data from an attribute or child tag. It is my suggestion to avoid such complex schemes but I'll give a simple example for completeness.

我已经看到过去将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));
                }
            }
        }
    }
}

#3


0  

converting xml to objects using the flex simplexmldecoder class @flexExamples

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

#4


0  

Creating strong data types has several advantages, code completion and compile time syntax checking being the most important ones. Manual mappings can be done, but should be generated (and thus aren't really manual any more after all) to avoid being out of sync sooner or later.

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

Introspection-based general conversion libraries are versatile, easy to use, and should suffice for most use-cases.

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

JAXB is the standard for Java. ASXB provides a lightweight implementation of this idea for the Actionscript world. It uses explicit AS objects with annotations to (un)marshal objects from and to XML.

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

If you are forced to use XML on the wire, I'd suggest giving ASXB a closer look. If you're free to choose your format and have a supporting Server-side, Adobes own AMF format should be your choice, as it's directly supported in the language and has a much lower overhead during transport.

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

In our current project, we wrote small code generators which takes the external API of the Java side (source introspection, to also copy the Javadoc) and generate the AS classes from it during our build process. It was thus easy to switch from AMF to XML when external requirements forced us to do so.

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

PS: remember to add the compiler parameters to your flex config file to keep the annotations

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

#5


0  

AsBeanGen can do this. It generates value objects for DTD driven XML files.

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

#6


0  

A little while ago I started working on a Flex Library that will help serialize and deserialize Action Script objects to and from XML. All you have to do is create your model objects, put some annotations on the fields to let the serializer know how you want the field to be serialized (element, attribute, what name, etc) and the call the (de)serialization process.

不久之前,我开始研究一个Flex库,它将帮助将Action Script对象序列化和反序列化为XML。您所要做的就是创建模型对象,在字段上添加一些注释,让序列化器知道您希望如何序列化字段(元素,属性,名称等)以及调用(反)序列化过程。

I think it suits your needs.

我认为这符合您的需求。

If you want, you can check it out at http://code.google.com/p/flexxb/.

如果需要,可以访问http://code.google.com/p/flexxb/查看。

Hope this will prove to be helpful.

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

#1


3  

I don't think this can be done automatically. I generally create the a class to mirror the XML structure I have and then create a static class method to create an instance of the object given an XML node. For example:

我不认为这可以自动完成。我通常创建一个类来镜像我的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]);
       }
    }
  }

#2


1  

If you aren't tied to XML (e.g. you have an app server instead of a file server) you could consider using AMF (Action Message Format) to transfer the data. There are a few projects that expose AMF to servers including Adobe's own Blaze DS and community open source variants such as OpenAMF, AMFPHP, PyAMF and so on. This will give you the ability to transfer custom objects from the server to Flex, automatic parsing of data-types and type safety. Have a look at this comparison of data transfer options to get an idea of the relative merits.

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

That being said, XML can be very useful for things like app configuration data and in those instances you aren't running an app server. I agree with the other poster where I will immediately parse the xml into appropriate structures by hand. I usually store these with the post-fix VO (for Value Object) and I leave the members as public. I often do this hierarchically.

话虽这么说,XML对于应用程序配置数据以及那些没有运行应用程序服务器的实例非常有用。我同意另一张海报,我会立即用手将xml解析成适当的结构。我通常使用修复后的VO(对于Value Object)存储它们,并将成员保留为public。我经常分层次地这样做。

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;
    }
}
}

I've seen systems in the past that will bind XML element names to class definitions. These usually use some sort of introspection on the class to determine what properties to read off the xml or they will have some static class properties that map instance properties to xml tags or attributes. In my experience they are much more trouble than they are worth. It takes all of 2 seconds to add a new public property and a single line to read the data from an attribute or child tag. It is my suggestion to avoid such complex schemes but I'll give a simple example for completeness.

我已经看到过去将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));
                }
            }
        }
    }
}

#3


0  

converting xml to objects using the flex simplexmldecoder class @flexExamples

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

#4


0  

Creating strong data types has several advantages, code completion and compile time syntax checking being the most important ones. Manual mappings can be done, but should be generated (and thus aren't really manual any more after all) to avoid being out of sync sooner or later.

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

Introspection-based general conversion libraries are versatile, easy to use, and should suffice for most use-cases.

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

JAXB is the standard for Java. ASXB provides a lightweight implementation of this idea for the Actionscript world. It uses explicit AS objects with annotations to (un)marshal objects from and to XML.

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

If you are forced to use XML on the wire, I'd suggest giving ASXB a closer look. If you're free to choose your format and have a supporting Server-side, Adobes own AMF format should be your choice, as it's directly supported in the language and has a much lower overhead during transport.

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

In our current project, we wrote small code generators which takes the external API of the Java side (source introspection, to also copy the Javadoc) and generate the AS classes from it during our build process. It was thus easy to switch from AMF to XML when external requirements forced us to do so.

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

PS: remember to add the compiler parameters to your flex config file to keep the annotations

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

#5


0  

AsBeanGen can do this. It generates value objects for DTD driven XML files.

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

#6


0  

A little while ago I started working on a Flex Library that will help serialize and deserialize Action Script objects to and from XML. All you have to do is create your model objects, put some annotations on the fields to let the serializer know how you want the field to be serialized (element, attribute, what name, etc) and the call the (de)serialization process.

不久之前,我开始研究一个Flex库,它将帮助将Action Script对象序列化和反序列化为XML。您所要做的就是创建模型对象,在字段上添加一些注释,让序列化器知道您希望如何序列化字段(元素,属性,名称等)以及调用(反)序列化过程。

I think it suits your needs.

我认为这符合您的需求。

If you want, you can check it out at http://code.google.com/p/flexxb/.

如果需要,可以访问http://code.google.com/p/flexxb/查看。

Hope this will prove to be helpful.

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