Convert XML Data to Strong Flex Type

The project I'm working on will pull XML from a web server and build a data warehouse from it. The data will have certain main fields, but must be extended ... for example, I have it, and later you may need to add additional fields.

In a Flex application, I don't want a central data warehouse to work on XML objects or just put properties on objects. I want to have strong types, such as the Person class, that are created / populated from XML.

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

+4
source share
6 answers

I do not think that this can be done automatically. Usually I create a class to mirror the XML structure that I have, and then create a static class method to instantiate the object based on the XML node. For instance:

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]); } } } 
+3
source

If you are not tied to XML (for example, you have an application server instead of a file server), you might consider using AMF ( Action Message Format ) to transfer data. There are several projects that provide AMF servers, including Adobe Blaze DS and open open community options such as OpenAMF , AMFPHP , PyAMF , etc. This will give you the ability to transfer custom objects from the server to Flex, automatic parsing of data types and type safety. Check out this comparison of data transfer options for an idea of ​​the relative merits.

Thus, XML can be very useful for things like application configuration data, and in cases where you are not using the application server. I agree with another poster where I will immediately parse the xml in the appropriate structures manually. I usually store them using Post-fix VO (for the Value object), and I leave them public. I often do this hierarchically.

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

In the past, I have seen systems that associate XML element names with class definitions. Usually they use some kind of introspection in the class to determine which properties to read xml or they will have some properties of a static class that map instance properties to xml tags or attributes. In my experience, they are much more complicated than they are worth it. It takes only 2 seconds to add a new public object and one line to read data from an attribute or child tag. My suggestion is to avoid such complex schemes, but I will give a simple example of completeness.

 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)); } } } } } 
+1
source

Some time ago, I started working with the Flex library, which will help serialize and deserialize Action Script objects in and out of XML. All you have to do is create model objects, put some annotations in the fields so that the serializer knows how you want the field to be serialized (element, attribute, what name, etc.) And calling the serialization process (de) .

I think it suits your needs.

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

Hope this is helpful.

0
source

Creating strong data types has several advantages; the most important are code validation and compile-time syntax validation. Manual mappings can be performed, but must be generated (and therefore are not really manual) in order to avoid synchronization failure sooner or later.

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

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

If you are forced to use XML on a wire, I suggest taking a closer look at ASXB. If you can choose your own format and have a supporting server side, the native AMF Adobes format should be your choice, since it is directly supported in this language and has much lower overhead during transportation.

In our current project, we wrote small code generators that accept the external APIs of the Java side (source introspection, and also copy Javadoc) and generate AS classes from it during our build process. Thus, it was easy to switch from AMF to XML when external requirements forced us to do this.

PS: don't forget to add compiler options to your flex configuration file to save annotations

0
source

AsBeanGen can do this. It generates value objects for XML files managed by DTDs.

0
source

Source: https://habr.com/ru/post/1277601/


All Articles