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

advertisement

XML Data-Binding: Comparing Castor to .NET
by Niel Bornstein | Pages: 1, 2, 3, 4

Now that we've generated the source, and we understand it, we can start porting our client code. The code in MakeDogShow.cs will be very similar to MakeDogShow.java; besides our usual Java-to-C# porting issues, xsd does a couple of things in code generation we need to deal with.

First, as we noted earlier, xsd does not generate getXXX() and setXXX() methods. Instead, we'll have to change all those method calls to directly access the instance variables, whose names will match the names in the schema file exactly.

Second, while we dealt with Dog, Show, etc., directly in Java, the W3C XML Schema types are mapped to C# types with the same name; that is, DogType, ShowType, etc. So instead of instantiating a Dog, we'll instantiate a DogType.

Finally, the generated ShowType type does not have an Unmarshal() method. Instead, we'll use the XmlSerializer to marshal our objects to XML.

Here's our C# version of MakeDogShow:

using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;

public class MakeDogShow {
    public static void Main(string [] args) {
	try {
	    DogType [] dog = new DogType [2];
	    dog[0] = new DogType();
	    dog[0].id = 1;
	    dog[0].name = "Wil-Orion's Angus Highlander";
	    
	    dog[1] = new DogType();
	    dog[1].id = 2;
	    dog[1].name = "LenLear's Webmaster";
	    
	    BreedType breed = new BreedType();
	    breed.id = 1;
	    breed.name = "English Springer Spaniel";
	    breed.dog = dog;

	    JudgeType judge = new JudgeType();
	    judge.id = 1;
	    judge.firstName = "John";
	    judge.lastName = "Smith";
	    
	    ShowRingType showRing = new ShowRingType();
	    showRing.id = 1;
	    showRing.name = "1";
	    
	    JudgingType [] judging = new JudgingType [] 
	        {new JudgingType()};
	    judging[0].judge = judge;
	    judging[0].breed = breed;
	    judging[0].showRing = showRing;
	    judging[0].dateTime = DateTime.Now;
	    
	    ShowType show = new ShowType();
	    show.id = 1;
	    show.name = "O'Reilly Invitational Dog Show";
	    show.judging = judging;

	    XmlSerializer serializer = new XmlSerializer(
	        show.GetType());	    
	    TextWriter writer = new StreamWriter("show.xml");
	    serializer.Serialize(writer,show);
	    writer.Close();

	} catch (Exception e) {
	    Console.Error.Write(e);
	}
    }
}

It generates the following XML file which, while superficially different from the Java version, is the same syntactically.

<?xml version="1.0" encoding="utf-8"?>
<Show xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <id>1</id>
  <name>O'Reilly Invitational Dog Show</name>
  <judging>
    <breed>
      <id>1</id>
      <name>English Springer Spaniel</name>
      <dog>
        <id>1</id>
        <name>Wil-Orion's Angus Highlander</name>
      </dog>
      <dog>
        <id>2</id>
        <name>LenLear's Webmaster</name>
      </dog>
    </breed>
    <judge>
      <id>1</id>
      <firstName>John</firstName>
      <lastName>Smith</lastName>
    </judge>
    <showRing>
      <id>1</id>
      <name>1</name>
    </showRing>
    <dateTime>2002-07-13T13:52:21.6667232-04:00</dateTime>
  </judging>
</Show>

There and Back Again

Now that we've generated XML files from both Java and C#, the neat trick will be to see if we can load the data from one into the other. In Java, that's done with the generated Show.unmarshal() method, as demonstrated below:

package org.dogshow;

import java.io.FileReader;

public class LoadDogShow {
    public static void main(String [] args) {
	try {
	    FileReader reader = new FileReader("show.xml");
	    Show show = Show.unmarshal(reader);
	    
	    System.out.println(show.getJudging()[0].
                getBreed().getDog()[0].getName());

	    reader.close();
	} catch (Exception e) {
	    e.printStackTrace(System.err);
	}
    }
}

And in C#, it's done with the XmlSerializer.Deserialize() method, as shown here:


using System;
using System.IO;
using System.Xml.Serialization;

public class LoadDogShow {
    public static void Main(string [] args) {
	try {
	    StreamReader reader = new StreamReader("show.xml");
	    XmlSerializer serializer = new XmlSerializer(
	        typeof(ShowType));
	    ShowType show = (ShowType)serializer.Deserialize(reader);

	    Console.WriteLine(show.judging[0].breed.dog[0].name);

	    reader.Close();
	} catch (Exception e) {
	    Console.Error.Write(e);
	}
    }
}

Summing Up

So, what have we learned this time? First, that, given an W3C XML Schema, we can easily create classes that create XML and load existing XML, for both Java and C#. And, given those classes, it's relatively easy to write code that uses them to write portable data files, using XML. The fact that we used the same schema and data files in Java and C# proves once and for all that XML is a true interoperability language.

But Wait, There's More!

The xsd tool can do some other things, too. It can generate source code in a variety of languages (Visual Basic .NET and JScript.NET, in addition to C#). It can generate a new W3C XML Schema Description for any .NET source file. Finally, it can generate a DataSet subclass, suitable for use in XML-to-RDBMS mapping. And that's where we'll pick up next time, with a comparison of JDO to ADO.NET.



1 to 7 of 7
  1. xsi:nil="true"
    2004-09-01 16:17:10 xml11
  2. about references
    2003-10-10 15:08:33 Igal Greenberg
  3. Castor JDO does NOT conform to the Sun's JDO spec
    2002-09-24 11:50:58 Simon Ru
  4. The more complex aspects of XSD's
    2002-09-22 10:59:14 simon sprott
  5. validation in .Net?
    2002-07-30 13:29:04 Takuki Kamiya
  6. Castor .unmarshal and .marshall methods
    2002-07-30 07:54:39 Erik Ostermueller
  7. Very little meat in this article
    2002-07-26 07:43:09 Dare Obasanjo
1 to 7 of 7