Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

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.


Comment on this articleGot a comment or question on this article? Share them in our forum.
(* You must be a
member of XML.com to use this feature.)
Comment on this Article


Titles Only Titles Only Newest First
  • xsi:nil="true"
    2004-09-01 16:17:10 xml11 [Reply]

    How can we get Castor to generate this tpe of attribute for the nillable fields?

  • about references
    2003-10-10 15:08:33 Igal Greenberg [Reply]

    Dear Mr Niel Bornstein,
    thank you for your enlighting article. After reading your article I was intregued by two issues
    I am interested in reference preserving of the a non tree object graph that would only produce one xml element for object instance?
    Are there any open source xml serialization efforts (like castor) in .net?


    Many thanks

  • Castor JDO does NOT conform to the Sun's JDO spec
    2002-09-24 11:50:58 Simon Ru [Reply]

    Mr. Bornstein, in your article, you mentioned:


    "It also includes a chapter on Castor, an open source data binding framework, which uses the Java Data Objects (JDO) specification for database mapping.... "


    This is misleading. Castor JDO doesn't conform to the Sun JDO spec. This is the first question I asked and one of the reason I am hesitate to user Castor's JDO. see JDO FAQ section in Castor's website.


    "Does Castor JDO comply with the SUN JSR-000012 specification?


    No, Castor JDO doesn't comply with the SUN's JDO specification."

  • The more complex aspects of XSD's
    2002-09-22 10:59:14 simon sprott [Reply]

    Can castor or .net cope is substitution groups, choices, abstract or any elements? Or are they just limited to a basic hierarchy of elements & attributes?

  • validation in .Net?
    2002-07-30 13:29:04 Takuki Kamiya [Reply]

    I could not get a clear idea as to where/when you can validate the XML being constructed in .NET, though it looks like it is handled entirely by unmarshaller because there is no setter method where early validation could have been provided.

    • validation in .Net?
      2002-08-05 17:54:25 Niel Bornstein [Reply]

      It's a fair question, and one which I did not address in this article.


      Basically, the validation of an XML document with a particular schema is done with XmlValidatingReader. One approach might be to create an instance of the DogShow class, then use XmlSerializer to write it to a MemoryStream. Then create an XmlValidatingReader, set its ValidationType to ValidationType.Schema, add the schema to its XmlSchemaCollection, and call Read().


      The following code snippet, replacing the XmlWriter portion of the C# sample, should provide some direction:


      Stream stream = new MemoryStream();
      TextWriter writer = new StreamWriter(stream);
      serializer.Serialize(writer,show);


      stream.Seek(0,SeekOrigin.Begin);


      XmlValidatingReader reader = new XmlValidatingReader(new XmlTextReader(stream));
      reader.ValidationType = ValidationType.Schema;
      reader.Schemas.Add("", "DogShow.xsd");


      while (reader.Read()) {
      // do nothing
      }

  • Castor .unmarshal and .marshall methods
    2002-07-30 07:54:39 Erik Ostermueller [Reply]

    You article states that the Castor generated code is larger than the C# code, partly due to the .marshal, .unmarshal and .validate methods.


    Well, this doesn't have to be the case.
    If you pass the SourceGenerator the -nomarshal flag, it will not generate these methods.
    Then, you can use the Marshaller, Unmarshaller and Validator classes to get invoke this functionality.

    • Castor .unmarshal and .marshall methods
      2002-07-31 04:38:42 Niel Bornstein [Reply]

      Thanks for your constructive comment. Although I did mention Castor's flexibility in this regard early in the article, I should have pointed this out with respect to the generated code.

  • Very little meat in this article
    2002-07-26 07:43:09 Dare Obasanjo [Reply]

    I was hoping to be enlightened about the similarities and differences between Castor and XML Serialization in .NET but this article is little more than one long sample. Shorter samples would have been appreciated so that time could have been spent discussing the pros and cons of each approach to XML data bindings. If longer samples were absolutely necessary you could have provided them as downloads or links to them on another site so there would be room in the article for meat.


    Secondly I see that your next article is a comparison of JDO and ADO.NET. For your information, the current released version of ADO.NET is not really a comparable technology to JDO since ADO.NET is primarily about traditional access to relational data sources in much the same manner as JDBC while JDO is more about object-relational mapping. Microsoft ObjectSpaces which has been previewed in a number of places is the comparable technology to JDO. More information on ObjectSpaces can be obtained by Googling for "Microsoft ObjectSpaces" which should lead you to enough information to write an informative article about both technologies.