XML to VO – as easy as apple pie!? (demo included)

xml to vo debug dialog

I’m currently working with SOAP web services. While making adjustments to the classes of the wsdl Flex Builder class generator I discovered, that there is an easy way to decode / parse XML to VOs (value objects). The XMLDecoder inside the rpc package does the trick. I’m still confused why there are not more resources on the web regarding this topic but If you want to digg deeper, I strongly recommend reading these blog posts by Dominic De Lorenzo:

Flex 3, XML Schemas & automatic mapping of AS classes to XSD element definitions (Part 1)
Flex 3, XML Schemas & automatic mapping of AS classes to XSD element definitions (Part 2)

I’m not an XML pro and some things in his example I’m still not getting (namespaces in XML, yes well…). Also, his example is in Flex and I just wanted to have a basic example on how this could be useful for my work.

Example / Demo

You have to tell the XMLDecoder what XML node is assigend to which VO type. “Schema” is the magic word – so before feeding the actual XML data to the XMLDecoder the SchemaManager needs to know what the XML structure looks like. After that, you just have to map the schema types to your custom VOs.

You can take a look at the VO classes here:
FieldVo
GroupVo

And this’s the actual example implementation …

private var schemaXML:XML = 

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <xsd:element name="root" >
    <xsd:complexType >
      <xsd:sequence >
        <xsd:element minOccurs="0" maxOccurs="unbounded" name="group" type="group"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  
  <xsd:complexType name="group">
     <xsd:sequence>
      <xsd:element name="id" type="xsd:string" />
      <xsd:element name="field" type="field" minOccurs="0" maxOccurs="unbounded"/>
      <xsd:element name="group" type="group" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>
  
  <xsd:complexType name="field">
     <xsd:sequence>
      <xsd:element name="id" type="xsd:string" />
      <xsd:element name="index" type="xsd:int" />
      <xsd:element name="label" type="xsd:string" />
      <xsd:element name="visible" type="xsd:boolean" />
    </xsd:sequence>
  </xsd:complexType>  
  
</xsd:schema>;

private var dataXML:XML = 

<root>
  <group>
    <id>group01</id>
    <field>
      <id>field01</id>
      <index>1</index>
      <label>test field 01</label>
      <visible>1</visible>
    </field>
    <field>
      <id>field02</id>
      <index>2</index>
      <label>test field 02</label>
      <visible>0</visible>
    </field>
    <field>
      <id>field03</id>
      <index>3</index>
      <label>test field 03</label>
      <visible>1</visible>
    </field>
    <group>
      <id>group0101</id>
      <field>
        <id>field04</id>
        <index>4</index>
        <label>test field 04</label>
        <visible>1</visible>
      </field>      
      <field>
        <id>field05</id>
        <index>5</index>
        <label>test field 05</label>
        <visible>0</visible>
      </field>      
    </group>
  </group>
  <group>
    <id>group02</id>
    <field>
      <id>field06</id>
      <index>6</index>
      <label>test field 06</label>
      <visible>1</visible>
    </field>         
  </group>
</root>;
        
var schema:Schema = new Schema(schemaXML);

var schemaManager:SchemaManager = new SchemaManager();
schemaManager.addSchema(schema);

var schemaTypeRegistry:SchemaTypeRegistry = SchemaTypeRegistry.getInstance();
schemaTypeRegistry.registerClass(new QName(schema.targetNamespace.uri, "group"), GroupVo);
schemaTypeRegistry.registerClass(new QName(schema.targetNamespace.uri, "field"), FieldVo);

var qName:QName = new QName(schema.targetNamespace.uri, "root");

var xmlDecoder:XMLDecoder = new XMLDecoder();
xmlDecoder.schemaManager = schemaManager;
  
var result:* = xmlDecoder.decode(dataXML, qName);
trace(result);

You might want to set a breakpoint at the trace statement so you can click through the result object step by step.

Please contribute!
Did you ever work with the XMLDecoder? Do you think, that this might improve your workflow? Just tell us.

Comments