XML is garnering a reputation as a key technology for sharing information between systems and platforms. However, for this exchange to work, you must be able to define your XML data. In “Better living through XML schemas,” we introduced XML Schema Definition (XSD) schemas as a way to accomplish this. As we discussed, the .NET framework provides support for validating XML data against an XSD schema. It also includes a utility to generate classes from an XSD schema, fully instrumented with XML mapping attributes and ready for use with XmlSerializer. In this article, I will show you how to generate serialization classes and validate XML data using an XSD schema.
Putting the schema to work
When we introduced XSD schemas in the previous article, we created XML data and an associated schema. Now that we have a schema, we are ready to put it to use. You saw how to get XML data in and out of your own classes with XmlSerializer in “Make XML serialization a snap with .NET attributes.” However, in that situation, you had to create the classes and instrument them with XML mapping attributes. This time, we will get the .NET SDK utility Xsd.exe to do this for you.
Xsd.exe is the Swiss army knife for XML schemas. In addition to generating serialization classes from a schema, it can do the reverse and infer a schema from a type in a .NET assembly or from an XML data file. It can also convert schemas written in Microsoft’s older XML-Data Reduced (XDR) format, used with the MSXML3 parser, to XSD.
The following invocation generates XML serialization classes from Showtimes.xsd:
xsd /c /l:CS /n:Articles.TechRepublic.XmlSchemas Showtimes.xsd
The command generates classes (/c) in the language C# (/l:CS) and places those classes in the namespace (/n) Articles.TechRepublic.XmlSchemas. The classes are generated in Showtimes.cs, by default. Xsd.exe can generate classes in C#, Visual Basic.NET or JScript.
The generated code can be seen in Listing A, reformatted slightly for easier reading.
The classes are a straightforward translation of the schema. Subelements and attributes are rendered as public fields rather than properties. The XML mapping attributes are fully qualified even though the System.Xml.Serialization namespace is included. The XmlRoot attribute for Theater specifies the positional Namespace parameter to link the class to the XML namespace xsdShowtimes. The positional attribute parameter IsNullable=false is specified throughout to suppress XML generation for null object references. This isn’t necessary for Movie.minutes because the XML attribute is optional.
Once the code is generated, you’re free to modify it, perhaps overriding ToString in each class for output. Of course, if you rerun Xsd.exe, your changes will be overwritten.
Validating XML data
Now let’s use the serialization classes generated above with XmlSerializer. Here, the XML data is validated using the schema and the XmlValidatingReader class. The program in Listing B deserializes an input XML file, validating it with the specified XSD schema.
The key statements are located inside the try block in the Main. An XmlTextReader is created to read the input XML file. An XmlSchemaCollection is created, associating the input XSD schema with the xsdShowtimes namespace. Next, an XmlValidatingReader is created to use the text reader and the schema collection. A delegate for the static ReportError function is added to the validating reader’s ValidationEventHandler event. The validating reader calls through the delegate each time it discovers an error in the input XML. ReportError sets a private flag and reports each error to the console. Finally, an XmlSerializer is created to deserialize a Theater object, reading data through the validating reader.
The program output for the XML data mentioned at the beginning of this article is as follows:
Output:
>XmlIn theaterValid.xml Showtimes.xsd
theaterValid.xml is valid.
The XML data shown in Listing C is invalid. It contains an extra theater name element and a malformed phone number value. The program output is shown below the invalid XML.
.NET and XML
Now you’ve been introduced to some of the things that you can do with XML data and schemas, especially when it comes to data validation. You can also see how .NET may help you make XML part of your next project.