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