W3C XML Schema type system < - > CLR type system

Note: this entry has moved.

I've had some discussions with co-workers and colleages about the WXS (W3C XML Schema) type system and its relation with the CLR one. We all agree that many concepts in WXS don't map to anything existing in OO languages, such as derivation by restriction, content-ordering (i.e. sequence vs choice), etc. However, in the light of the tools the .NET Framework makes available to map XML to objects, we usually have to analyze WXS (used to define the structure of that very XML instance to be mapped) and its relation with our classes.

When you use the XmlSerializer to get a CLR object filled with data in the XML, you're actually mapping it to the CLR type system. Moreover, when you use xsd.exe /classes tool, you're effectively translating WXS types to CLR ones. You get classes with System.String type corresponding to xs:string, and the like. Dare explains this in his article in MSDN. The .NET Framework documentation about the XmlSerializer class explicitly states:

To transfer data between objects and XML requires a mapping from the programming language constructs to XML Schema and vice versa. The XmlSerializer, and related tools like Xsd.exe, provide the bridge between these two technologies at both design time and run time.

Even the XmlValidatingReader.ReadTypedValue performs this map transparently for simple types, which is thoroughly documented in the product documentation under the title Data Type Support between XML Schema (XSD) Types and .NET Framework Types. At the PDC, new and even more comprehensive mapping tools/approaches were shown.

But let's go beyond the simpleType (almost) natural mapping between WXS and the CLR. We can have an abstract complexType in WXS named Person, and derive by extension Employee and Customer ones. Our root element, which will be a list of the contacts we know about, can be a choice of any of them, like so:

<?xml version="1.0" encoding="utf-8" ?> <xs:schema id="XSDTypeSystem" targetNamespace="http://aspnet2.com/xsdvsclr" \ elementFormDefault="qualified" xmlns="http://aspnet2.com/xsdvsclr" xmlns:mstns="http://aspnet2.com/xsdvsclr" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- The base abstract type --> <xs:complexType name="Person" abstract="true"> <xs:sequence> <xs:element name="FirstName" type="xs:string" /> <xs:element name="LastName" type="xs:string" /> </xs:sequence> </xs:complexType> <xs:complexType name="Employee"> <xs:complexContent> <xs:extension base="Person"> <xs:sequence> <xs:element name="EmployeeID" type="xs:string" /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name="Customer"> <xs:complexContent> <xs:extension base="Person"> <xs:sequence> <xs:element name="CustomerID" type="xs:string" /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:element name="Contacts"> <xs:complexType> <xs:choice> <xs:element name="Customer" type="Customer" maxOccurs="unbounded" minOccurs="0" /> <xs:element name="Employee" type="Employee" maxOccurs="unbounded" minOccurs="0" /> </xs:choice> </xs:complexType> </xs:element> </xs:schema>

Now, what do you think such types would look in .NET world? Well, I don't think it takes an expert in WXS to realize that these types map nicely with an abstract Person class, and Employee and Customer derived types. We can confirm that by running xsd.exe /classes with this schema, and we will get the following .NET classes:

/// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://aspnet2.com/xsdvsclr")] [System.Xml.Serialization.XmlRootAttribute(Namespace="http://aspnet2.com/xsdvsclr", IsNullable=false)] public class Contacts { /// <remarks/> [System.Xml.Serialization.XmlElementAttribute("Employee", typeof(Employee))] [System.Xml.Serialization.XmlElementAttribute("Customer", typeof(Customer))] public Person[] Items; } /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://aspnet2.com/xsdvsclr")] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Customer))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Employee))] public abstract class Person { /// <remarks/> public string FirstName; /// <remarks/> public string LastName; } /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://aspnet2.com/xsdvsclr")] public class Employee : Person { /// <remarks/> public string EmployeeID; } /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://aspnet2.com/xsdvsclr")] public class Customer : Person { /// <remarks/> public string CustomerID; }

Note that the XSD tool was even smart enough to realize that as both expected elements in the WXS choice for the Contact element inherit from the same Person type, they can actually be part of the same array type, which is defined as Person[] Items. That looks like a pretty nice fit.

In this light, I'm conducting a survey about developer's view on the relation of the XSD type system and the .NET one. Ignoring some of the more advanced (I could add cumbersome and confusing) features of WXS, would you say that both type systems fit nicely with each other?

Valid votes (through comments, will be summed up in this post description) are: YES (they fit nicely) and NO (they don't).

The later sort of implies that you think MS is pushing the similarities too far, and that it's not good. I look forward your comments and votes!

Current votation: YES=13, NO=0

8 Comments

Comments have been disabled for this content.