XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

XML Data-Binding: Comparing Castor to .NET

July 24, 2002

After the second article in this series was published, several readers said that they would like to learn the .NET way to map data from XML to a relational database management system. I'd like to show you that, but first I've got to lay some groundwork. In this article, I will show how .NET XML data binding works, while investigating the equivalent Java functionality. Java and .NET both have excellent support for data binding, and although they work in slightly different ways, each is just as valid and useful as the other. In my next article, I'll complete the exercise by mapping XML files to an RDBMS.

To begin by sounding my usual theme, there are several ways to do it in Java. In fact, Brett McLaughlin has written an entire book about several of the many ways to do XML databinding. Appropriately titled "Java & XML Databinding", its main topic is mapping XML to Java objects with the Java™ Architecture for XML Binding (JAXB). It also includes a chapter on Castor, an open source data binding framework, which uses the Java Data Objects (JDO) specification for database mapping, as well as providing XML data binding through a non-JAXB interface. Castor effectively serves as a bridge between XML and a database, with Java objects as an intermediary layer.

Go, Bind Thou Up Young Dangling Apricots

The first side of Castor is its interface for binding XML documents to Java objects. There's not enough room here for us to go into all the details, but we will go through the following two steps.

  1. Define the mappings from XML to Java, either procedurally or through configuration files (which may themselves may either be W3C XML Schema documents or in Castor's own format).
  2. Either generate Marshaller and Unmarshaller classes specific to our data (for best performance) or allow Castor to manage the marshaling and unmarshaling at runtime (for most flexibility).

There are many options to customize your Castor project; for the most balanced comparison to .NET, we'll stick to W3C XML Schema and Castor's built-in runtime marshaling. Unlike many of the other Java databinding frameworks, Castor includes excellent W3C XML Schema support.

Our example in this article will be a dog show. The dog show's domain objects are the show itself, the dogs, dog breeds, judges, and show rings. Each breed is evaluated by a particular judge in a particular show ring at a particular time, and each breed contains dogs to be judged, so we've got a nice model with just enough objects and relationships to be interesting.

We'll be using W3C XML Schema to define our marshaling, so let's get right down to the model, presented here in W3C XML Schema. It's called DogShow.xsd.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:complexType name="ShowType">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="id" 
        type="xs:long" />
      <xs:element minOccurs="1" maxOccurs="1" name="name" 
        type="xs:string" />
      <xs:element minOccurs="1" maxOccurs="unbounded" 
        name="judging" type="JudgingType" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="BreedType">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="id" 
        type="xs:long" />
      <xs:element minOccurs="1" maxOccurs="1" name="name" 
        type="xs:string" />
      <xs:element minOccurs="1" maxOccurs="unbounded" 
        name="dog" type="DogType" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="DogType">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="id" 
        type="xs:long" />
      <xs:element minOccurs="1" maxOccurs="1" name="name" 
        type="xs:string" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="JudgeType">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="id" 
        type="xs:long" />
      <xs:element minOccurs="1" maxOccurs="1" 
        name="firstName" type="xs:string" />
      <xs:element minOccurs="1" maxOccurs="1" 
        name="lastName" type="xs:string" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ShowRingType">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="id" 
        type="xs:long" />
      <xs:element minOccurs="1" maxOccurs="1" name="name" 
        type="xs:string" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="JudgingType">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" 
        name="breed" type="BreedType" />
      <xs:element minOccurs="1" maxOccurs="1" 
        name="judge" type="JudgeType" />
      <xs:element minOccurs="1" maxOccurs="1" 
        name="showRing" type="ShowRingType" />
      <xs:element minOccurs="1" maxOccurs="1" 
        name="dateTime" type="xs:dateTime" />
    </xs:sequence>
  </xs:complexType>

  <xs:element name="Show" nillable="false" 
        type="ShowType" />
  <xs:element name="Breed" nillable="true" 
        type="BreedType" />
  <xs:element name="Dog" nillable="true" 
        type="DogType" />
  <xs:element name="Judge" nillable="true" 
        type="JudgeType" />
  <xs:element name="ShowRing" nillable="true" 
        type="ShowRingType" />
  <xs:element name="Judging" nillable="true" 
        type="JudgingType" />

</xs:schema>

Given this schema, we can use Castor's source generator to build Java source with the following command (you will need to have downloaded the Castor jar file, as well as having an XML parser in your CLASSPATH; I'm using Xerces, from the Apache XML project):

java org.exolab.castor.builder.SourceGenerator -i DogShow.xsd -package org.dogshow

(Answer "A" to replace any files that get created during the code generation process.)

And we can compile the generated sources with this command line:

javac org\dogshow\*.java


Pages: 1, 2, 3, 4

Next Pagearrow