Support for XSD and Validation of Typed Nodes


In many of the previous examples, we used explicit casting and accessed nodes through their names as quoted strings. All those casts and quotes are not type safe and cannot be checked at compile time. However, XML document structure is often defined using an XML Schema Definition (XSD). There is a LINQ to XSD project that allows access to XML nodes using a typed and self-describing approach, and it is supported by Microsoft IntelliSense. For instance, the last query you saw in the previous section would be written like the one in Listing 6-35.

Listing 6-35: A LINQ query over XML, based on an XSD typed approach

image from book
  var ordersWithCustomersFromXml =     from    c in xmlCustomers.customerCollection     join    o in orders     on      c.Name equals o.Name     orderby c.Name     select  new {                 Name = c.Name,                 City = c.City,                 IdProduct = o.IdProduct,                 Quantity = o.Quantity }; 
image from book

As you can see, when using this approach the XML nodes graphs look like any other object graphs-regardless of whether they are made of elements, attributes, or nodes instead of objects. Keep in mind that the LINQ to XSD project is still under construction at the time of writing this book.

XML schema support is also offered through some extension methods defined in the System.Xml.Schema.Extensions class of the System.Xml.Linq assembly. There are just a couple of methods with a few overloads. Those methods are GetSchemaInfo, which extends any XElement or XAttribute instance, and Validate, which extends XDocument, XElement,and XAttribute. The first method (GetSchemaInfo) returns an annotation of type System.Xml.Schema.IXmlSchemaInfo taken from the current node, if present. It retrieves a schema definition mapped to the current node by using LINQ to XML annotations. The Validate method, as you can figure out from its name, validates the source XML node using an XmlSchemaSet containing the schemas to use. Consider the XML schema shown in Listing 6-36.

Listing 6-36: An XML Schema Definition for our sample list of customers

image from book
  <?xml version="1.0" encoding="utf-8" ?> <xsd:schema      targetNamespace="http://schemas.devleap.com/Customer"     elementFormDefault="qualified"     xmlns="http://schemas.devleap.com/Customer"     xmlns:xsd="http://www.w3.org/2001/XMLSchema">   <xsd:element name="customers">     <xsd:complexType>       <xsd:sequence>         <xsd:element name="customer" minOccurs="0" maxOccurs="unbounded">           <xsd:complexType>             <xsd:attribute name="name" type="xsd:string" use="required" />             <xsd:attribute name="city" type="xsd:string" use="required" />             <xsd:attribute name="country">               <xsd:simpleType>                 <xsd:restriction base="xsd:string">                   <xsd:enumeration value="Italy" />                   <xsd:enumeration value="USA" />                 </xsd:restriction>               </xsd:simpleType>             </xsd:attribute>           </xsd:complexType>         </xsd:element>       </xsd:sequence>     </xsd:complexType>   </xsd:element> </xsd:schema> 
image from book

You can define an XML graph with this structure, using LINQ to XML as usual, and map the nodes to the previous schema using an XNamespace instance. An example is shown in Listing 6-37.

Listing 6-37: An XML document with the schema of Listing 6-36, built using the LINQ to XML API

image from book
  XNamespace ns = "http://schemas.devleap.com/Customer"; XDocument xmlCustomers = new XDocument(     new XElement(ns + "customers",         from   c in customers         select new XElement(ns + "customer",                    new XAttribute("city", c.City),                    new XAttribute("name", c.Name),                    new XAttribute("country", c.Country)))); 
image from book

At this point, you have the xmlCustomers variable that represents an XML Infoset instance related to the schema of Listing 6-36 using its corresponding XML namespace.

In Listing 6-38, you can see how to validate this XDocument using the Validate extension method.

Listing 6-38: XML validation using the Validate extension method

image from book
  static void validateXDocument() {     // ...     XmlSchemaSet schemas = new XmlSchemaSet();     schemas.Add(XmlSchema.Read(new StreamReader(@"..\..\customer.xsd"), null));     xmlCustomers.Validate(schemas, xmlCustomers_validation); } static void xmlCustomers_validation(Object source, ValidationEventArgs args) {     // In case of validation messages     Console.WriteLine(args.Message); } 
image from book

The Validate method internally uses all the standard and common classes and tools of the System.Xml.Schema namespace.




Introducing Microsoft LINQ
Introducing MicrosoftВ® LINQ
ISBN: 0735623910
EAN: 2147483647
Year: 2007
Pages: 78

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net