xmlbeans in c sort of

Thu, Sep 3, 2009

I use XMLBeans extensively in Java so I don’t have to work with raw XML, especially SAX, as it’s a real pain to deal with. XMLBeans, given an XSD and xsdconfig will create a load of Java classes that map directly to the XML documents. All very nice but what about C#? When I was doing the C++ version of GADfly I was back into raw XML but there is something quite nice you can use in C# to get much the same effect as XMLBeans. It’s called xsd.exe

If you give it a schema and some params it’ll create classes you can serialize/deserialize to/from XML. Let’s say you have this simple schema:

<schema targetNamespace=“some:daft:urn”
        xmlns:sdu=“some:daft:urn”
        xmlns=“http://www.w3.org/2001/XMLSchema"
        elementFormDefault=“qualified”
        attributeFormDefault=“unqualified”
        blockDefault=“substitution”
        version=“2.0”>

<complexType name=“userType”> <sequence> <element name=“userid” type=“string”/> <element name=“email” type=“string” minOccurs=“0”/> </sequence> </complexType>

<element name=“identity”> <complexType> <sequence> <element name=“user” type=“ib:userType” /> </sequence> </complexType> </element>

</schema>

this will get you a partial class to work with the above schema:
xsd domain.xsd /c /l:cs /o:.
You can then read XML straight into C# classes:
XmlSerializer serializer = new XmlSerializer(typeof(identity));
TextReader xmlReader = new StringReader(xml);
identity id = (identity)serializer.Deserialize(xmlReader);
Console.WriteLine(id.user.userid);
There are a couple of things to note. The schema types can’t be mapped as they can in XMLBeans but that doesn’t matter as you have access to the top level objects, such as identity and user, so if you’re going to be working exclusively in C# it would be an idea to name the top level types in accordance with C# class naming conventions. The biggest gotcha is whether you want to work with namespaces. This is where it gets messy. XML namespace is different from C# namespace. Where you can call an XML namespace anything, in this case I’ve called it some:daft:urn, you cannot call C# namespaces anything. If you want to generate the classes into a specific namespace you use this command:
xsd domain.xsd /c /l:cs /n:some:daft:urn /o:.
but the classes won’t compile as this is not correct:
namespace some:daft:urn {
}
So whereas XMLBeans provides a language neutral XML abstraction, it’s best to use xsd.exe for C# bindings alone, where you control the schemata. You just can’t use it in a general scenario as the XML namespaces are very likely to cause you a lot of trouble.

comments powered by Disqus