[interop] Consuming a .NET Typed DataSet from Java
Well, as with most things it's dead simple once you get the hang of it. With the help from Jan-Erik, Jdev 10g and XML Spy 4.0 it's not that hard. First I coded up a couple of Web Services in .NET. One method returned a typed DataSet containing both authors and titles, another returned a "typed" XML document (node actually) version created from the typed DataSet:
public XmlNode GetTypedXmlDocument()
{
PubsDataSet dsp = GetTypedDataSets();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml(dsp.GetXml());
return xmlDoc.DocumentElement;
}
It's very simple to generate SOAP client code from within Jdev that will call my Web Service methods, so I won't get into that. Both my .NET web methods will return an org.w3c.dom.Element (Jdev detects this automatically) and if you're into XML and XPath, you can very well start hacking away at the XML data you got. But being used to .NET typed DataSets, this isn't what I like. So, what you do is get hold of XML Spy and point at the schema location of the typed PubsDataSet in it. When the schema has been loaded into XML Spy, goto DTD/Schema->Generate Program Code... and select Java as the program language. XML Spy will now generate a couple of classes for you based on that Schema, which you now can import and use in Jdev:
Service1Stub ws = new Service1Stub();
try
{
//Testing typed DataSet, need to manipulate the stub code
Element e = ws.GetTypedDataSets();
PubsDataSetType ds = new PubsDataSetType((Element)e.getElementsByTagName("PubsDataSet").item(0));
System.out.println(" --- Typed DataSet --- ");
System.out.println(" No of authors: " + ds.getauthorsCount());
System.out.println(" No of titles: " + ds.gettitlesCount());
System.out.println(" An author: " + ds.getauthorsAt(0).getau_fname());
//Testing "typed" xml document
ds = new PubsDataSetType(ws.GetTypedXmlDocument());
System.out.println(" --- Typed XmlDocument --- ");
System.out.println(" No of authors: " + ds.getauthorsCount());
System.out.println(" No of titles: " + ds.gettitlesCount());
System.out.println(" An author: " + ds.getauthorsAt(1).getau_fname());
}
catch (Exception e)
{
System.err.println("Exception getting DataSet:" + e.toString());
}
Sorry about the non-existing colors ;)
As you can see, for the first sample you need to get hold of the first occation of the "PubsDataSet" node because the typed DataSet contains schemas for author and titles, which the XML Spy generated classes doesn't like :) This is not needed for the "typed" xml document, because it only contains the xml data we're interested in. The first example (the typed DataSet) also need a little hack in the Jdev generated service-stub:
public Element GetTypedDataSets() throws Exception
{
URL endpointURL = new URL(_endpoint);
...removed a lot of proxy code...
// return (Element)fromElement((Element)responseData.elementAt(0), org.w3c.dom.Element.class);
return (Element) responseData.elementAt(0);
}
That's about it. As you can see, the "typed" xml document, need no cryptic code-changes at all. Just feed the return XML Element to the PubsDataSetType constructor, and you're home. The output from above is:
--- Typed DataSet ---
No of authors: 23
No of titles: 18
An author: Johnson
--- Typed XmlDocument ---
No of authors: 23
No of titles: 18
An author: Marjorie
I'll ask Jan-Erik and see if we cannot write some kind of article about this. If anyone is interested that is :)