JiBX: Structure Mapping

Structure Mapping

JiBX's binding definition file provides great flexibility for converting between XML documents and Java object structures. Other data binding frameworks generally limit customization to just the names and the style (attribute or element) of XML representations. JiBX goes further by allowing structure mapping between XML and object structures.

To see what's meant by structure mapping, consider the following XML fragment:

<customer>
  <name>
    <first-name>John</first-name>
    <last-name>Smith</last-name>
  </name>
  <street1>12345 Happy Lane</street1>
  <city>Plunk</city>
  <state>WA</state>
  <zip>98059</zip>
  <phone>888.555.1234</phone>
</customer>

Most data binding frameworks will support mapping this fragment to instances of classes along the lines of:

  public class Customer {
    public Name name;
    public String street1;
    public String city;
    public String state;
    public String zip;
    public String phone;
  }
  
  public class Name {
    public String firstName;
    public String lastName;
  }

Here's a JiBX binding that handles this base case, with some color coding to show related items (blue for the binding of the <name> element to the Name class, green for the binding of the values within the <name> element to fields of the Name class:

Direct binding

Most frameworks will allow you to change the names of the fields in the mapping - to use customerName instead of name, and first rather than firstName, for example. Some frameworks will use get/set methods rather than public fields, but the principle remains the same. JiBX supports both types of access, as well as allowing renaming. That's just the start of JiBX features, though.

What most frameworks will not allow you to do is to bring the values within the name element into the the object that corresponds to the customer element. In other words, you can't map the XML to this class:

  public class Customer {
    public String firstName;
    public String lastName;
    public String street1;
    public String city;
    public String state;
    public String zip;
    public String phone;
  }

Nor can you map the XML to a pair of classes like these:

  public class Customer {
    public String firstName;
    public String lastName;
    public Address address;
    public String phone;
  }
  
  public class Address {
    public String street1;
    public String city;
    public String state;
    public String zip;
  }

JiBX does allow you to do this type of mapping. This means the structure of your objects is not tied to the structure of the XML - you can restructure your object classes without needing to change the XML format used for external data transfer. The diagram below shows a binding definition for the first case above:

Flattened binding

The only difference in this binding definition from the first example is that I've removed the field attribute from the structure element. The structure still defines an XML element name, but without the field attribute the values within that XML element are treated as properties of the containing object (the Customer class instance).

Adding a new structure element to the binding definition handles the second structure change case, as shown in the diagram below:

Split binding

Here the added structure element uses a field attribute but no name attribute. This tells JiBX that the properties from the Address class instance referenced by the address field should be included directly as children of the <customer> element in the XML document.

The flexibility provided by structure mapping allows you to decouple your XML data representations from your actual Java class structure. It lets you interface existing code to new XML representations, and also lets you preserve an existing XML representation while refactoring your code to better represent the use of data within your application. This decoupling of XML structure from code structure is one of the most powerful features of the JiBX framework.

Next: Advanced Binding Features