I've started to implement a web service, sending and receiving XML snippets to a vendor. I was browsing their
documentation, and was about to start throwing together some code using string functions to build/parse the XML, and then
I remembered all the hubub I've heard about generating code using XML files, and figured there might be some tools out
there to make this go a lot smoother. The vendor was kind enough to provide a sample XML file and a Document Type Definition (DTD) file, so
now all I need to do is convert that to C# classes.
First try: xsd.exe
The first tool I looked at was
xsd.exe
, a command line tool bundled with Visual Studio. When I dug in, I see that it can:
- convert a XML Schema Definition (XSD) file into C# classes
- convert a sample XML file into a XSD file, inferring and guessing as to the details
- convert an External Data Representation (XDR, what the hell is that one?) file into a XSD file, inferring and
guessing as to the details
- generate XSD files for .NET classes in a file or assembly
So... no option for converting a DTD. Ok, time to google for DTD XSD converters.
Second try: dtd2xs and xsd.exe
The first hit was dtd2xs. This is a Java based converter that
can be run from the commandline, used as a library in java programs, and as an applet in webpage. It convienently
comes with some HTML that already has the applet set up, so I loaded up that page and tried to convert my
DTD. After a few seconds, I was presented with a window listing some debug info, and then a line with:
******************** Copy & Paste ********************
and nothing underneath it, where I would expect to see content to Copy and Paste. I ran it again with the same result, and
then viewed source on the frame. The source had the XSD document in there, but wasn't being rendered because all the XML was
meaningless to Firefox. I copied the content into an .xsd file, and then ran
xsd.exe on it. The result? A bunch of
errors about invalid references in the XSD. Maybe I can fix the XSD file using Visual Studio's XSD tools.
Third try: Visual Studio
Next, I tried to use the XSD editor in Visual Studio to see if I could correct the problem. I messed around with the raw XML
of the XSD file, guessing what attributes like "ref" and "name" would mean in the context of defining data. After messing around
with the file, I was able to generate even less sensical errors from xsd.exe. Had I put in the time to learn the XSD
XML dialect, then I'm sure these errors would make sense, but I've no interest in learning more XML acronyms. There's enough of those
in my head already. I decided to try to build it from scratch using Visual Studio's GUI XSD editor.
I dragged an "element" block from the toolbox, added some attributes, and then promptly gave up.
The UI wasn't that great (few tooltips, ambiguous context menu options), and it wasn't clear how to do what should be simple things.
I figure if I'm going to spend time learning how to use a tool, I'd rather use one that will be more efficient, so I'll put my effort
into the command line tools.
Fourth try: xsd.exe again
I decided to take a different approach:
- use
xsd.exe to generate an XSD from my sample XML file.
- use
xsd.exe can generate C# from that XSD.
This actually worked. The result C# was very much generated code, but it had the plumbing to save/load from an XML file or string, and
that is the plumbing I was wanting the most. I took a look at the XSD to glean a bit of knowledge, and started to see the gaps left
by inferring schema from a sample. Default values for attributes were lost, all enumerations were lost (when an attribute's value is
restricted to certain values), all the optional stuff was missing, and overall I wasn't too pleased with the results. I could probably
make it work, but I'd get a much higher quality result if I could retain as much of the vendor's definition as possible. Back to google
for another dtd xsd converter.
Fifth try: Xsdvalid and xsd.exe
The next converter I found was Xsdvalid. This is a sub-component
of a larger XML editor, XMLmind XML Editor.
Xsdvalid is another Java program (I guess Java folks love XML), able to be used as a library or from the command line. I ran
my DTD through it, and it came out with a much larger XSD than dtd2xs. xsd.exe ran without errors on the
first try, and the resulting C# had enums for the enumerations defined in the DTD, and seemed a lot better. My C# is now directly based on
the vendor's definition, with no opportunity for me to make mistakes in translating.
Conclusion
I haven't actually used the generated code yet, but will be writing some unit tests momentarily for parsing/building. I do have high hopes,
so bless you people with XML fetishes for doing this work for me. Also, curse you people with XML fetishes for not picking *one*
XML dialect to describe XML documents and causing this task in the first place.