LINQ to XSD Mapping Documentation

Important: You must accept the enclosed license terms before you can use this pre-release software. If you do not accept the License Terms, you are not authorized to use this pre-release software. The License Terms are included in the distribution of this software.


Who should read this?

The following document systematically describes the mapping of XML schemas to .NET object models. The normal user of the LINQ to XSD technology is not necessarily assumed to work with this documentation. The idea is that the implemented mapping is mostly intuitive and that intellisense and object browsing provide sufficient help for the developer. The documentation mainly serves as an informal specification.

Notice: LINQ to XSD is an incubation project on typed XML programming carried out at Microsoft. LINQ to XSD is not scheduled to ship as a product. It is important to note that this release is being exposed to customers so as to gather their feedback on the typed XML programming experience. Any future products in this space may or may not be similar to LINQ to XSD. See the license terms for details.


Notational conventions for OO APIs


The resulting .NET classes are described in C#-like pseudo code so as to hide routine technicalities.


OO API (Illustration of notation)

class Foo : XTypedElement
{
   constructor  Foo();
   explicit cast  Foo(System.Xml.Linq.XElement xe);
   property  string  Bar  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Table of contents


Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Global types and elements

Subsections

Further reading



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Complex-type definitions

Complex-type definitions are mapped to classes.
Each generated class comprises the following members:

  • a default constructor;
  • an explicit cast from XElement to the defined class;
  • some inherited API members such as Save; see the LINQ to XSD manual;
  • further members depending on the content model.
The class that is generated for a complex type subclasses XTypedElement.
In fact, a derived complex-type is mapped to a subclass of the class that is generated for its base type.

Schema sample (Complex-type definitions)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- A complex type for addresses -->

     <xs:complexType name="Address">
          <!-- address details omitted -->

     </xs:complexType>

</xs:schema>

OO API

class Address : XTypedElement
{
   constructor  Address();
   explicit cast  Address(System.Xml.Linq.XElement xe);
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Roots with anonymous, complex types

We use the term "root" to refer to global element declarations in an XML schema.
We recall that a valid instance must be necessarily rooted in an element of that kind.
Such roots are essentially mapped in the same way as complex-type definitions.

Schema sample (Roots with anonymous, complex types)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- A global element declaration for addresses -->

     <xs:element name="Address">
          <xs:complexType>
               <!-- address details omitted -->

          </xs:complexType>

     </xs:element>

</xs:schema>

OO API

class Address : XTypedElement
{
   constructor  Address();
   explicit cast  Address(System.Xml.Linq.XElement xe);
}

The conceptual difference between complex-type definitions and root element declarations is worth recalling: The latter define proper types in the sense of sets of elements, whereas the former model "incomplete" elements because element tags are not prescribed. This conceptual difference is reflected in the behavior of the generated object types. That is, the complex-type name serves as "preliminary" element tag for any instance of the class that corresponds to the complex type in question; this preliminary tag is eventually resolved to a proper element tag, when the instance is parented or when it is wrapped in a root element. Note:  Save and Load members are potentially misleading for classes that were generated from complex-type definitions since de-/serialization is only well-defined for root-element declarations. It is conceivable that a future release of LINQ to XSD makes explicit the conceptual difference between complex-type definitions and root element declarations.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Roots with type references to complex types

This pattern makes combined use of a complex-type definition and a global element declaration.

Schema sample (Roots with type references to complex types)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="BillTo" type="Address"/>

     <xs:element name="ShipTo" type="Address"/>

     <xs:complexType name="Address">
          <xs:sequence>
               <xs:element name="Name" type="xs:string"/>

               <!-- ... -->

          </xs:sequence>

     </xs:complexType>

</xs:schema>

This style is mapped as follows:
  • The following classes are generated in this case:

    • There is one class for each element declaration ("the envelope").
    • There is one class for each complex type ("the content").
  • Envelopes can be constructed from content by means of a non-default constructor.
  • The content can be extracted from the envelope by means of the Content member.
  • The "envelope" class implements the API of the "content" class by forwarding.

OO API (Roots with type references to complex types)

class Address : XTypedElement
{
   constructor  Address();
   explicit cast  Address(System.Xml.Linq.XElement xe);
   property  string  Name  getset; }
}
class BillTo : XTypedElement
{
   constructor  BillTo();
   constructor  BillTo(Address content);
   explicit cast  BillTo(System.Xml.Linq.XElement xe);
   property  Address  Content  get;  }
   property  string  Name  getset; }
}
class ShipTo : XTypedElement
{
   constructor  ShipTo();
   constructor  ShipTo(Address content);
   explicit cast  ShipTo(System.Xml.Linq.XElement xe);
   property  Address  Content  get;  }
   property  string  Name  getset; }
}

The combined use of element declarations and complex-type definitions leads to potentially convoluted object models, when the most direct mapping is applied. Hence, this usage pattern of XSD may suggest schema normalizations. Note: The current release of LINQ to XSD does not yet provide any relevant schema normalization.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Simple-type definitions

Schema sample (Simple-type definitions)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:simpleType name="Month">
          <xs:restriction base="xs:token">
               <!-- restriction facets omitted -->

          </xs:restriction>

     </xs:simpleType>

</xs:schema>

By default, simple-type definitions are not mapped to any class that the programmer is supposed to instantiate. Note: The current release of LINQ to XSD generates a vacuous class for each simple-type definition. This class should be omitted. By customization, one can also request a class that is designated to a simple-type definition. Note: This option not supported by the current release of LINQ to XSD. The use of designated classes offers two benefits: (i) simple-type names from the XML schema can be used in program code; (ii) substitutability for simple types (say, subtyping in OO terms) can be precisely expressed.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Roots with anonymous, simple types

Root element declarations (with anonymous types or not) are mapped to classes.

Schema sample (Roots with anonymous, simple types)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="Month">
          <xs:simpleType>
               <xs:restriction base="xs:string">
                    <!-- restriction facets omitted -->

               </xs:restriction>

          </xs:simpleType>

     </xs:element>

</xs:schema>

OO API

class Month : XTypedElement
{
   constructor  Month();
   explicit cast  Month(System.Xml.Linq.XElement xe);
   property  string  TypedValue  getset; }
}

The (simple) content of such root elements can be access with a designated TypedValue property (akin to LINQ to XML's untyped value property). The type of this property is the built-in base type of the anonymous simple type. As usual, the class also provides an explicit coercion (cast) from XElement to the class.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Roots with type references to simple types

Schema sample (Roots with type references to simple types)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="Month" type="MonthType"/>

     <xs:simpleType name="MonthType">
          <xs:restriction base="xs:string">
               <!-- restriction facets omitted -->

          </xs:restriction>

     </xs:simpleType>

</xs:schema>

OO API

class Month : XTypedElement
{
   constructor  Month();
   constructor  Month(string content);
   explicit cast  Month(System.Xml.Linq.XElement xe);
   property  string  TypedValue  getset; }
}

The (simple) content of such root elements can be access with a designated TypedValue property (akin to LINQ to XML's untyped value property). The type of this property is the OO counterpart for the built-in XSD base type of the referenced simple type. As usual, the class also provides an explicit coercion (cast) from XElement to the class.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Content models

Subsections

Executive summary
  • Element particles are mapped to properties.
  • Properties exhibit an XPath-like semantics for the child axis.
  • Sequence groups map to a group of properties for their element particles.
  • Choices are mapped like sequences + mutual exclusion semantics.
  • Optionality is modeled with null or nullable.
  • Repetition is modeled with IList.
  • Element-name recurrence maps to single properties.
  • The nesting of content models is not directly exhibited by the resulting API.
  • The API for nested content models is limited in terms of construction and updates.
  • Local element declarations of an anonymous types imply a nested class.
  • Element and attribute wildcards are mapped to special properties.


Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Flat sequences

Characteristics of flat sequences:

  • The content model is defined by a sequence group.
  • The sequence compositor occurs directly below a named complex-type element.
  • The children of the sequence group are (local) element declarations.
  • The names of the elements in the sequence are distinct.
For now, additional restrictions are assumed, for mere simplicity:
  • The hosting complex type does not declare any attributes.
  • The elements in the sequence are required.
Without loss of generality, we use a complex-type definition to host the content model.
(That is, we could also use a root-element declaration.)

Schema sample (Flat sequences)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- A very simple type of addresses -->

     <xs:complexType name="Address">
          <xs:sequence>
               <xs:element name="Name" type="xs:string"/>

               <xs:element name="Zip" type="xs:int"/>

               <xs:element name="Street" type="xs:string"/>

          </xs:sequence>

     </xs:complexType>

</xs:schema>

Flat sequences are mapped as follows:

OO API

class Address : XTypedElement
{
   constructor  Address();
   explicit cast  Address(System.Xml.Linq.XElement xe);
   property  string  Name  getset; }
   property  int  Zip  getset; }
   property  string  Street  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Type and element references

Executive summary

  • There are OO counterparts for the built-in XSD simple types.
  • Element references are mapped to the class name for the referenced element.
  • Likewise for type references for complex types.
  • Derived simple types do not "nominally" participate in the mapping.
  • The name of a local element declaration defines the property name.
  • Element names and names of referenced types are subject to name mapping.
The following schema exercises type references for simple and complex types.

Schema sample (Type references)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- A host for the references to follow -->

     <xs:complexType name="Customer">
          <xs:sequence>
               <xs:element name="Name" type="xs:string"/>

               <xs:element name="Age" type="AgeType"/>

               <xs:element name="Address" type="AddressType"/>

          </xs:sequence>

     </xs:complexType>

     <!-- A complex type to be referenced -->

     <xs:complexType name="AddressType">
          <xs:sequence>
               <xs:element name="Zip" type="xs:int"/>

               <xs:element name="Street" type="xs:string"/>

          </xs:sequence>

     </xs:complexType>

     <!-- A simple type to be referenced -->

     <xs:simpleType name="AgeType">
          <xs:restriction base="xs:int">
               <xs:minInclusive value="0"/>

               <xs:maxInclusive value="200"/>

          </xs:restriction>

     </xs:simpleType>

</xs:schema>

Simple-type references are mapped, by default, to references of the OO counterpart of the built-in XSD base type of the referenced type.
The constraints for the simple type are enforced by the properties for the corresponding elements.
Note: In the current release of LINQ to XSD, setters are validated, but not getters. This may be change.
Complex-type references are always mapped to the class name for the complex type.

OO API (Type references)

class Customer : XTypedElement
{
   constructor  Customer();
   explicit cast  Customer(System.Xml.Linq.XElement xe);
   property  string  Name  getset; }
   property  int  Age  getset; }
   property  AddressType  Address  getset; }
}
class AddressType : XTypedElement
{
   constructor  AddressType();
   explicit cast  AddressType(System.Xml.Linq.XElement xe);
   property  int  Zip  getset; }
   property  string  Street  getset; }
}

The following schema varies the above schema such that:
  • It uses element declarations instead of type definitions;
  • It uses element references instead of local element declarations with type references.

Schema sample (Element references)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- A host for the references to follow -->

     <xs:element name="Customer">
          <xs:complexType>
               <xs:sequence>
                    <xs:element name="Name" type="xs:string"/>

                    <xs:element ref="Age"/>

                    <xs:element ref="Address"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

     <!-- A referable element of a complex type -->

     <xs:element name="Address">
          <xs:complexType>
               <xs:sequence>
                    <xs:element name="Zip" type="xs:int"/>

                    <xs:element name="Street" type="xs:string"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

     <!-- A referable element of a simple type -->

     <xs:element name="Age">
          <xs:simpleType>
               <xs:restriction base="xs:int">
                    <xs:minInclusive value="0"/>

                    <xs:maxInclusive value="200"/>

               </xs:restriction>

          </xs:simpleType>

     </xs:element>

</xs:schema>

Element references are always mapped to "wrapper" references.
This rule is applied regardless of whether the content model is or complex.

OO API (Element references)

class Customer : XTypedElement
{
   constructor  Customer();
   explicit cast  Customer(System.Xml.Linq.XElement xe);
   property  string  Name  getset; }
   property  Age  Age  getset; }
   property  Address  Address  getset; }
}
class Address : XTypedElement
{
   constructor  Address();
   explicit cast  Address(System.Xml.Linq.XElement xe);
   property  int  Zip  getset; }
   property  string  Street  getset; }
}
class Age : XTypedElement
{
   constructor  Age();
   explicit cast  Age(System.Xml.Linq.XElement xe);
   property  int  TypedValue  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Optional elements

An element is optional, if the (local) element declaration is attributed as follows:

  • There is an attribute minOccurs="0".
  • The value of the maxOccurs is 1 (which is the default).
The mapping of optionality depends on the mapping of the involved content type:
  • If the element type is mapped to a CLR-value type, then optionality maps to nullable types.
  • Otherwise, optionality is not explicitly represented by the resulting CLR reference type.
  • Clearly, all complex-content types are mapped to CLR reference types.
  • Hence, optional and required elements of a complex content type are mapped in the same way.

Schema sample (Optional elements)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- Customer information with optional age and shipping-address information -->

     <xs:complexType name="Customer">
          <xs:sequence>
               <xs:element name="Name" type="xs:string"/>

               <xs:element name="Age" type="xs:int" minOccurs="0"/>

               <xs:element name="BillAddress" type="Address"/>

               <xs:element name="ShipAddress" type="Address" minOccurs="0"/>

          </xs:sequence>

     </xs:complexType>

     <!-- Part 1 of street address is required; part 2 is optional -->

     <xs:complexType name="Address">
          <xs:sequence>
               <xs:element name="Zip" type="xs:int"/>

               <xs:element name="Street1" type="xs:string"/>

               <xs:element name="Street2" type="xs:string" minOccurs="0"/>

          </xs:sequence>

     </xs:complexType>

</xs:schema>

OO API (Use of nullable types)

class Customer : XTypedElement
{
   constructor  Customer();
   explicit cast  Customer(System.Xml.Linq.XElement xe);
   property  string  Name  getset; }
   property  int?  Age  getset; }
   property  Address  BillAddress  getset; }
   property  Address  ShipAddress  getset; }
}
class Address : XTypedElement
{
   constructor  Address();
   explicit cast  Address(System.Xml.Linq.XElement xe);
   property  int  Zip  getset; }
   property  string  Street1  getset; }
   property  string  Street2  getset; }
}

Given the missing disoverability of optionality for reference types, the classes generated by LINQ to XSD may document optionality as part of the tool tips for the relevant properties.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Repeating elements

An element is repeating, if the element declaration is attributed as follows:

  • The value of the maxOccurs attribute is different from 0 and 1 (default).
  • We say that the particle is a possibly empty list particle if minOccurs="0".
  • Otherwise, we say that the particle is a non-empty list particle.
The mapping of repeating elements is defined as follows:
  • Suppose t is result of mapping the element type of the particle.
  • Then, the property type for the mapped element particle is IList appled to t.
  • Hence, the observable CLR type does not resemble the precise occurrence constraints.

Schema sample (Repeating elements)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- A figure is a potentially empty list of lines. -->

     <xs:element name="Figure">
          <xs:complexType>
               <xs:sequence>
                    <xs:element ref="Line" minOccurs="0" maxOccurs="unbounded"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

     <!-- A line consists of 2 or more points. -->

     <xs:element name="Line">
          <xs:complexType>
               <xs:sequence>
                    <xs:element ref="Point" minOccurs="2" maxOccurs="unbounded"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

     <xs:element name="Point">
          <xs:complexType>
               <xs:sequence>
                    <xs:element name="xCoord" type="xs:int"/>

                    <xs:element name="yCoord" type="xs:int"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

</xs:schema>

OO API (Use of IList interface)

class Figure : XTypedElement
{
   constructor  Figure();
   explicit cast  Figure(System.Xml.Linq.XElement xe);
   property  IList<Line>  Line  getset; }
}
class Line : XTypedElement
{
   constructor  Line();
   explicit cast  Line(System.Xml.Linq.XElement xe);
   property  IList<Point>  Point  getset; }
}
class Point : XTypedElement
{
   constructor  Point();
   explicit cast  Point(System.Xml.Linq.XElement xe);
   property  int  xCoord  getset; }
   property  int  yCoord  getset; }
}

Given the missing disoverability of non-empty versus empty list status (or more specific bounds than 0, 1 and unbounded), the class that are generated by LINQ to XSD may document the status as part of the tool tips for the relevant properties.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Attributes

Attribute declarations are mapped to properties that are added to the class that hosts the complex type of which the attributes are part of. (For simplicity, it is assumed that element and attribute names are distinct in a given scope. Otherwise, special rules of name mapping apply.)

Schema sample (A complex type with an attribute declaration)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:complexType name="Product">
          <xs:sequence>
               <xs:element name="Number" type="xs:integer"/>

               <xs:element name="Name" type="xs:string"/>

          </xs:sequence>

          <xs:attribute name="EffDate" type="xs:date" use="optional"/>

     </xs:complexType>

</xs:schema>

OO API

class Product : XTypedElement
{
   constructor  Product();
   explicit cast  Product(System.Xml.Linq.XElement xe);
   property  decimal  Number  getset; }
   property  string  Name  getset; }
   property  System.DateTime?  EffDate  getset; }
}

OO API (Properties for attributes)

class Product : XTypedElement
{
   constructor  Product();
   explicit cast  Product(System.Xml.Linq.XElement xe);
   property  decimal  Number  getset; }
   property  string  Name  getset; }
   property  System.DateTime?  EffDate  getset; }
}

All attribute declarations can be thought as element particles in a sequence.
Hence, the following schema maps to the same object model as the earlier schema.

Schema sample (Elements in place of attributes)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:complexType name="Product">
          <xs:sequence>
               <xs:element name="Number" type="xs:integer"/>

               <xs:element name="Name" type="xs:string"/>

               <xs:element name="EffDate" type="xs:date" minOccurs="0"/>

          </xs:sequence>

     </xs:complexType>

</xs:schema>



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Flat choices

Characteristics of flat choices:

  • The content model is defined by a choice group.
  • The compositor occurs directly below a complex-type element.
  • The children of the choice group are (local) element declarations.
  • The element names are distinct (required per XSD validity).
  • The element types are described by type references.

Schema sample (Flat choice)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="BillTo">
          <!-- Both street and pobox are of type xs:string. -->

          <xs:complexType>
               <xs:choice>
                    <xs:element name="Street" type="xs:string"/>

                    <xs:element name="Pobox" type="xs:string"/>

               </xs:choice>

          </xs:complexType>

     </xs:element>

</xs:schema>

The choice group is essentially mapped as the same sequence group except that:

OO API (Flat choices on element particles)

class BillTo : XTypedElement
{
   constructor  BillTo();
   explicit cast  BillTo(System.Xml.Linq.XElement xe);
   property  string  Street  getset; }
   property  string  Pobox  getset; }
}

Programmatic case discrimination choices can be based on non-null tests per branch that are appropriate casceded in conditionals. For a more restricted form of choices, convenience for construction can be provided. That is, when the choice at hand uses plain element particles with distinct element types that are also mapped to different OO types, then we can use the (mapped) types themselves to provide an overloaded constructor.

Schema sample (A choice with distinct element types for the branches)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- Arithmetic expression forms combined by choice -->

     <xs:complexType name="Exp">
          <xs:choice>
               <xs:element name="Const" type="xs:int"/>

               <xs:element name="Add" type="Add"/>

          </xs:choice>

     </xs:complexType>

     <!-- Addition as an expression form -->

     <xs:complexType name="Add">
          <xs:sequence>
               <xs:element name="Left" type="Exp"/>

               <xs:element name="Right" type="Exp"/>

          </xs:sequence>

     </xs:complexType>

</xs:schema>

Note that there are two constructors, corresponding to a binary choice.

OO API

class Exp : XTypedElement
{
   constructor  Exp();
   constructor  Exp(int? Const);
   constructor  Exp(Add Add);
   explicit cast  Exp(System.Xml.Linq.XElement xe);
   property  int?  Const  getset; }
   property  Add  Add  getset; }
}
class Add : XTypedElement
{
   constructor  Add();
   explicit cast  Add(System.Xml.Linq.XElement xe);
   property  Exp  Left  getset; }
   property  Exp  Right  getset; }
}

The described mapping rules do not readily enable the discoverability of mutually exclusive properties (in the sense of choice), when compared to the combined use of properties (in the sense of sequence). The classes generated by LINQ to XSD may document the content model as part of the tool tips for the relevant properties.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Recurrent element names

An element name is said to be recurrent in a given content model, if the content model comprises multiple element declarations of the given name. Recurrence is mapped such that all the relevant element declarations are mapped to a single property with a type as in the case of a repeating element particle. That is, there is no 1:1 correspondence of element particles and properties; instead there is 1:1 correspondence of element names and properties.

Schema sample (Recurrent element names)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- A figure as a list of lines -->

     <xs:element name="Figure">
          <xs:complexType>
               <xs:sequence>
                    <xs:element ref="Line" minOccurs="0" maxOccurs="unbounded"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

     <!-- A line that consist of two points. -->

     <xs:element name="Line">
          <xs:complexType>
               <xs:sequence>
                    <xs:element ref="Point"/>

                    <xs:element ref="Point"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

     <xs:element name="Point">
          <xs:complexType>
               <xs:sequence>
                    <xs:element name="xCoord" type="xs:int"/>

                    <xs:element name="yCoord" type="xs:int"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

</xs:schema>

OO API

class Figure : XTypedElement
{
   constructor  Figure();
   explicit cast  Figure(System.Xml.Linq.XElement xe);
   property  IList<Line>  Line  getset; }
}
class Line : XTypedElement
{
   constructor  Line();
   explicit cast  Line(System.Xml.Linq.XElement xe);
   property  IList<Point>  Point  getset; }
}
class Point : XTypedElement
{
   constructor  Point();
   explicit cast  Point(System.Xml.Linq.XElement xe);
   property  int  xCoord  getset; }
   property  int  yCoord  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Nested content models

Schema sample (Nested, repeating sequences)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:complexType name="JobOffer">
          <xs:sequence>
               <xs:element name="JobId" type="xs:string"/>

               <xs:sequence minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="Name" type="xs:string"/>

                    <xs:element name="SSN" type="xs:int"/>

               </xs:sequence>

          </xs:sequence>

     </xs:complexType>

</xs:schema>

The LINQ to XSD mapping is instance-oriented. That is, the nesting of compositors is not represented by the API of the classes generated by LINQ to XSD. Instead, all element names in a content model give rise to properties. We refer to the discussion of "append semantics" in the overview and the manual for LINQ to XSD.

OO API

class JobOffer : XTypedElement
{
   constructor  JobOffer();
   explicit cast  JobOffer(System.Xml.Linq.XElement xe);
   property  string  JobId  getset; }
   property  IList<string>  Name  getset; }
   property  IList<int>  SSN  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Anonymous types

The mapping for root elements with anonymous types was defined elsewhere. The mapping for local elements with anonymous simple types is trivial because the (derived) simple type or the type union or list type is reduced to the base built-in type as far as the API type is concerned. The case of local elements with anonymous complex types remains.

Schema sample (A schema with nested, anonymous, complex types)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="Bib">
          <xs:complexType>
               <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Book">
                         <xs:complexType>
                              <xs:sequence>
                                   <xs:choice maxOccurs="unbounded">
                                        <xs:element name="Title" type="xs:string"/>

                                        <xs:element maxOccurs="unbounded" name="Author">
                                             <xs:complexType>
                                                  <xs:sequence>
                                                       <xs:element name="Last" type="xs:string"/>

                                                       <xs:element name="First" type="xs:string"/>

                                                  </xs:sequence>

                                             </xs:complexType>

                                        </xs:element>

                                        <xs:element name="Editor">
                                             <xs:complexType>
                                                  <xs:sequence>
                                                       <xs:element name="Last" type="xs:string"/>

                                                       <xs:element name="First" type="xs:string"/>

                                                       <xs:element name="Affiliation">
                                                            <xs:complexType>
                                                                 <xs:simpleContent>
                                                                      <xs:extension base="xs:string">
                                                                           <xs:attribute name="Type" type="xs:string" use="required"/>

                                                                      </xs:extension>

                                                                 </xs:simpleContent>

                                                            </xs:complexType>

                                                       </xs:element>

                                                  </xs:sequence>

                                             </xs:complexType>

                                        </xs:element>

                                        <xs:element name="Publisher" type="xs:string"/>

                                        <xs:element name="Price" type="xs:decimal"/>

                                   </xs:choice>

                              </xs:sequence>

                              <xs:attribute name="Year" type="xs:unsignedShort" use="required"/>

                              <xs:attribute name="Anson" type="xs:boolean" use="optional"/>

                              <xs:attribute name="Joe" type="xs:string" use="optional"/>

                         </xs:complexType>

                    </xs:element>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

</xs:schema>

By default, such nesting of elements and types is mapped to nesting of OO classes.

OO API (Default mapping)

class Bib : XTypedElement
{
   constructor  Bib();
   explicit cast  Bib(System.Xml.Linq.XElement xe);
   
class BookLocalType : XTypedElement
{
   constructor  BookLocalType();
   explicit cast  BookLocalType(System.Xml.Linq.XElement xe);
   
class AuthorLocalType : XTypedElement
{
   constructor  AuthorLocalType();
   explicit cast  AuthorLocalType(System.Xml.Linq.XElement xe);
   property  string  Last  getset; }
   property  string  First  getset; }
}
   
class EditorLocalType : XTypedElement
{
   constructor  EditorLocalType();
   explicit cast  EditorLocalType(System.Xml.Linq.XElement xe);
   
class AffiliationLocalType : XTypedElement
{
   constructor  AffiliationLocalType();
   explicit cast  AffiliationLocalType(System.Xml.Linq.XElement xe);
   property  string  TypedValue  getset; }
   property  string  Type  getset; }
}
   property  string  Last  getset; }
   property  string  First  getset; }
   property  AffiliationLocalType  Affiliation  getset; }
}
   property  IList<string>  Title  getset; }
   property  IList<AuthorLocalType>  Author  getset; }
   property  IList<EditorLocalType>  Editor  getset; }
   property  IList<string>  Publisher  getset; }
   property  IList<decimal>  Price  getset; }
   property  ushort  Year  getset; }
   property  bool?  Anson  getset; }
   property  string  Joe  getset; }
}
   property  IList<BookLocalType>  Book  getset; }
}

However, one can also request a transformation for de-anonymization. The topic of schema normalization is discussed in the LINQ to XSD manual. De-anonymization modifies the mapping such that anonymous complex types are defined globally, while the local element names are leveraged as type names, when this is possible without introducing type clashes. Accordingly, the resulting object model does not comprise any nested classes.

OO API (Mapping with de-anonymization)

class Bib : XTypedElement
{
   constructor  Bib();
   explicit cast  Bib(System.Xml.Linq.XElement xe);
   property  IList<Book>  Book  getset; }
}
class Book : XTypedElement
{
   constructor  Book();
   explicit cast  Book(System.Xml.Linq.XElement xe);
   property  IList<string>  Title  getset; }
   property  IList<author>  author  getset; }
   property  IList<Editor>  Editor  getset; }
   property  IList<string>  Publisher  getset; }
   property  IList<decimal>  Price  getset; }
   property  ushort  Year  getset; }
   property  bool?  Anson  getset; }
   property  string  Joe  getset; }
}
class author : XTypedElement
{
   constructor  author();
   explicit cast  author(System.Xml.Linq.XElement xe);
   property  string  Last  getset; }
   property  string  First  getset; }
}
class Editor : XTypedElement
{
   constructor  Editor();
   explicit cast  Editor(System.Xml.Linq.XElement xe);
   property  string  Last  getset; }
   property  string  First  getset; }
   property  Affiliation  Affiliation  getset; }
}
class Affiliation : XTypedElement
{
   constructor  Affiliation();
   explicit cast  Affiliation(System.Xml.Linq.XElement xe);
   property  string  TypedValue  getset; }
   property  string  Type  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Fixed and default values

Note:  The current release of LINQ to XSD provides incomplete/disabled support for fixed and default values. At the time of writing, default attributes were still to be expected for the release, but all other forms of fixed and default values were not expected for the release.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Wildcards

Schema sample (A schema with wildcards)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:complexType name="ProductType">
          <xs:sequence>
               <xs:element name="Number" type="xs:string"/>

               <xs:element name="Name" type="xs:string"/>

               <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="lax"/>

          </xs:sequence>

          <xs:anyAttribute namespace="##other" processContents="skip"/>

     </xs:complexType>

</xs:schema>

Element wildcards are mapped to a designated API member.
Note: Attribute wildcards are ignored by the mapping in the current release of LINQ to XSD and hence require the untyped API.

OO API (Designated members for wildcards)

class ProductType : XTypedElement
{
   constructor  ProductType();
   explicit cast  ProductType(System.Xml.Linq.XElement xe);
   property  string  Number  getset; }
   property  string  Name  getset; }
   property  IEnumerable<System.Xml.Linq.XElement>  Any  get;  }
}

The Any property is always of type XElement or a list type thereof. Occurrence constraints and recurrence of Any are subject to the same rules as for normal element particles. That is, if the Any is neither repeating nor recurring, then the generated property is of type XElement. Otherwise, the property is of the list type.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Substitution forms

Subsections



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Complex-type extension

For simplicity, the following assumptions are made:

  • A complex base type is extended by complex content.
  • Substitutability is unrestricted, i.e., block and final are not used.
  • The derived content model is a sequence on element particles.
  • The derived type is non-anonymous.

Schema sample

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- A base type of products -->

     <xs:complexType name="Product">
          <xs:sequence>
               <xs:element name="Number" type="xs:integer"/>

               <xs:element name="Name" type="xs:string"/>

          </xs:sequence>

     </xs:complexType>

     <!-- shirt extends product -->

     <xs:complexType name="Shirt">
          <xs:complexContent>
               <xs:extension base="Product">
                    <xs:sequence>
                         <xs:element name="Size" type="xs:string"/>

                         <xs:element name="Color" type="xs:string"/>

                    </xs:sequence>

               </xs:extension>

          </xs:complexContent>

     </xs:complexType>

     <!-- hat extends product -->

     <xs:complexType name="Hat">
          <xs:complexContent>
               <xs:extension base="Product">
                    <xs:sequence>
                         <xs:element name="Size" type="xs:int"/>

                    </xs:sequence>

               </xs:extension>

          </xs:complexContent>

     </xs:complexType>

</xs:schema>

Such type derivation by extension is mapped as follows:
  • Both base type and derived type are mapped to classes.
  • The derivation relationship is mapped to OO class inheritance.
  • That is, the "derived" class inherits from the "base" class.
  • Roots in the derivation hierarchy inherit from "XTypedElement" as usual.
  • The properties for the added particles appear in the derived class.

OO API

class Product : XTypedElement
{
   constructor  Product();
   explicit cast  Product(System.Xml.Linq.XElement xe);
   property  decimal  Number  getset; }
   property  string  Name  getset; }
}
class Shirt : Product
{
   constructor  Shirt();
   explicit cast  Shirt(System.Xml.Linq.XElement xe);
   property  string  Size  getset; }
   property  string  Color  getset; }
}
class Hat : Product
{
   constructor  Hat();
   explicit cast  Hat(System.Xml.Linq.XElement xe);
   property  int  Size  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Extension of simple content

Note: This topic is not documented in the current release of LINQ to XSD.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Simple-type restriction

Note: This topic is not documented in the current release of LINQ to XSD.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Complex-type restriction

Schema sample

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- A base type of products -->

     <xs:complexType name="Product">
          <xs:sequence>
               <xs:element name="Number" type="xs:integer"/>

               <xs:element name="Name" type="xs:string"/>

               <xs:element name="Size" type="xs:int" minOccurs="0"/>

               <xs:element name="Color" type="xs:string" minOccurs="0"/>

          </xs:sequence>

     </xs:complexType>

     <!-- A restriction of product -->

     <xs:complexType name="RigidProduct">
          <xs:complexContent>
               <xs:restriction base="Product">
                    <xs:sequence>
                         <xs:element name="Number" type="xs:integer"/>

                         <xs:element name="Name" type="xs:string"/>

                         <xs:element name="Size" type="xs:int"/>

                    </xs:sequence>

               </xs:restriction>

          </xs:complexContent>

     </xs:complexType>

</xs:schema>

The derived type is mapped to a subclass of the class for the base type.
Note: In the current release of LINQ to XSD, the restrictions are not checked in any way.

OO API

class Product : XTypedElement
{
   constructor  Product();
   explicit cast  Product(System.Xml.Linq.XElement xe);
   property  decimal  Number  getset; }
   property  string  Name  getset; }
   property  int?  Size  getset; }
   property  string  Color  getset; }
}
class RigidProduct : Product
{
   constructor  RigidProduct();
   explicit cast  RigidProduct(System.Xml.Linq.XElement xe);
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Susbstitution groups

Here is an example for using substitution groups.
(We continue the example on
type derivation by extension for complex types.)

Schema sample (Substitution groups)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="Product" type="ProductType"/>

     <xs:element name="Shirt" type="ShirtType"/>

     <xs:element name="Hat" type="HatType"/>

     <xs:complexType name="ProductType">
          <xs:sequence>
               <!-- product details omitted -->

          </xs:sequence>

     </xs:complexType>

     <xs:complexType name="ShirtType">
          <xs:complexContent>
               <xs:extension base="ProductType">
                    <xs:sequence>
                         <!-- shirt details omitted -->

                    </xs:sequence>

               </xs:extension>

          </xs:complexContent>

     </xs:complexType>

     <xs:complexType name="HatType">
          <xs:complexContent>
               <xs:extension base="ProductType">
                    <xs:sequence>
                         <!-- hat details omitted -->

                    </xs:sequence>

               </xs:extension>

          </xs:complexContent>

     </xs:complexType>

</xs:schema>

Substitution groups are mapped in accordance to the combined use of element declarations and complex-type definitions .
In addition, the following mapping rules apply:
  • The type derivation hierarchy is mapped as in the case of plain type derivation.
  • The global element declarations are mapped as usual except for the superclass constraint.
  • Classes for substitution group members inherit from the class for the head.

OO API

class ProductType : XTypedElement
{
   constructor  ProductType();
   explicit cast  ProductType(System.Xml.Linq.XElement xe);
}
class ShirtType : ProductType
{
   constructor  ShirtType();
   explicit cast  ShirtType(System.Xml.Linq.XElement xe);
}
class HatType : ProductType
{
   constructor  HatType();
   explicit cast  HatType(System.Xml.Linq.XElement xe);
}
class Product : XTypedElement
{
   constructor  Product();
   constructor  Product(ProductType content);
   explicit cast  Product(System.Xml.Linq.XElement xe);
   property  ProductType  Content  get;  }
}
class Shirt : XTypedElement
{
   constructor  Shirt();
   constructor  Shirt(ShirtType content);
   explicit cast  Shirt(System.Xml.Linq.XElement xe);
   property  ShirtType  Content  get;  }
}
class Hat : XTypedElement
{
   constructor  Hat();
   constructor  Hat(HatType content);
   explicit cast  Hat(System.Xml.Linq.XElement xe);
   property  HatType  Content  get;  }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Control of substitutability

Note: This topic is not documented in the current release of LINQ to XSD.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Trivially mapped XSD constructs

Subsections



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Group definitions

These definitions are not mapped. References to these definitions are mapped by inlining them in the place of the reference. Note: This approach may be refined in a future version of LINQ to XSD so that groups are mapped for better code factorization.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Global attribute declarations

These declarations are not mapped.
References to these declarations are mapped by inlining them in the place of the reference.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Global attribute-group definitions

These definitions are not mapped.
References to these definitions are mapped by inlining them in the place of the reference.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Redefinitions

The System.Xml.Schema semantics of redefinitions applies.
Essentially, this implies that redefinitions override the original definitions.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Identity constraints

Identity constraints are not taken into account, in any way.
Normal validation is supposed to check these constraints.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Mixed content

There are no designated API members for mixed content.
Interim text is discoverable and definable through the XElement interface.
Tool tips may document the mixed-content status of a class.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Appendix: Mapping of built-in simple types

By default, each and every XSD built-in simple type is mapped to a CLR type, mostly to a CLR value type or to string. This default mapping is exercised below by means of a content model with an element particle for each and every built-in type.

Schema sample (All of XSD's built-in simple types)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <!-- An illustrative type that exercises all built-in simple types. -->

     <!-- Indeed, all these types are listed in alphabetic order. -->

     <xs:complexType name="simpleType">
          <xs:sequence>
               <xs:element name="xsAnySimpleType" type="xs:anySimpleType"/>

               <xs:element name="xsAnyURI" type="xs:anyURI"/>

               <xs:element name="xsBase64Binary" type="xs:base64Binary"/>

               <xs:element name="xsBoolean" type="xs:boolean"/>

               <xs:element name="xsByte" type="xs:byte"/>

               <xs:element name="xsDate" type="xs:date"/>

               <xs:element name="xsDateTime" type="xs:dateTime"/>

               <xs:element name="xsENTITIES" type="xs:ENTITIES"/>

               <xs:element name="xsENTITY" type="xs:ENTITY"/>

               <xs:element name="xsFloat" type="xs:float"/>

               <xs:element name="xsDecimal" type="xs:decimal"/>

               <xs:element name="xsDouble" type="xs:double"/>

               <xs:element name="xsDuration" type="xs:duration"/>

               <xs:element name="xsGDay" type="xs:gDay"/>

               <xs:element name="xsGMonth" type="xs:gMonth"/>

               <xs:element name="xsGMonthDay" type="xs:gMonthDay"/>

               <xs:element name="xsGYear" type="xs:gYear"/>

               <xs:element name="xsGYearMonth" type="xs:gYearMonth"/>

               <xs:element name="xsHexBinary" type="xs:hexBinary"/>

               <xs:element name="xsID" type="xs:ID"/>

               <xs:element name="xsIDREF" type="xs:IDREF"/>

               <xs:element name="xsIDREFS" type="xs:IDREFS"/>

               <xs:element name="xsInt" type="xs:int"/>

               <xs:element name="xsInteger" type="xs:integer"/>

               <xs:element name="xsLanguage" type="xs:language"/>

               <xs:element name="xsLong" type="xs:long"/>

               <xs:element name="xsName" type="xs:Name"/>

               <xs:element name="xsNCName" type="xs:NCName"/>

               <xs:element name="xsNegativeInteger" type="xs:negativeInteger"/>

               <xs:element name="xsNMTOKEN" type="xs:NMTOKEN"/>

               <xs:element name="xsNMTOKENS" type="xs:NMTOKENS"/>

               <xs:element name="xsNonNegativeInteger" type="xs:nonNegativeInteger"/>

               <xs:element name="xsNonPositiveInteger" type="xs:nonPositiveInteger"/>

               <xs:element name="xsNormalizedString" type="xs:normalizedString"/>

               <!-- xs:NOTATION was omitted since it is only used in derivations. -->

               <xs:element name="xsPositiveInteger" type="xs:positiveInteger"/>

               <xs:element name="xsQName" type="xs:QName"/>

               <xs:element name="xsUnsignedByte" type="xs:unsignedByte"/>

               <xs:element name="xsUnsignedInt" type="xs:unsignedInt"/>

               <xs:element name="xsUnsignedLong" type="xs:unsignedLong"/>

               <xs:element name="xsUnsignedShort" type="xs:unsignedShort"/>

               <xs:element name="xsShort" type="xs:short"/>

               <xs:element name="xsString" type="xs:string"/>

               <xs:element name="xsTime" type="xs:time"/>

               <xs:element name="xsToken" type="xs:token"/>

          </xs:sequence>

     </xs:complexType>

</xs:schema>

OO API (CLR counteparts for XSD built-in simple types)

class simpleType : XTypedElement
{
   constructor  simpleType();
   explicit cast  simpleType(System.Xml.Linq.XElement xe);
   property  string  xsAnySimpleType  getset; }
   property  System.Uri  xsAnyURI  getset; }
   property  System.Byte[]  xsBase64Binary  getset; }
   property  bool  xsBoolean  getset; }
   property  sbyte  xsByte  getset; }
   property  System.DateTime  xsDate  getset; }
   property  System.DateTime  xsDateTime  getset; }
   property  IList<string>  xsENTITIES  getset; }
   property  string  xsENTITY  getset; }
   property  float  xsFloat  getset; }
   property  decimal  xsDecimal  getset; }
   property  double  xsDouble  getset; }
   property  System.TimeSpan  xsDuration  getset; }
   property  System.DateTime  xsGDay  getset; }
   property  System.DateTime  xsGMonth  getset; }
   property  System.DateTime  xsGMonthDay  getset; }
   property  System.DateTime  xsGYear  getset; }
   property  System.DateTime  xsGYearMonth  getset; }
   property  System.Byte[]  xsHexBinary  getset; }
   property  string  xsID  getset; }
   property  string  xsIDREF  getset; }
   property  IList<string>  xsIDREFS  getset; }
   property  int  xsInt  getset; }
   property  decimal  xsInteger  getset; }
   property  string  xsLanguage  getset; }
   property  long  xsLong  getset; }
   property  string  xsName  getset; }
   property  string  xsNCName  getset; }
   property  decimal  xsNegativeInteger  getset; }
   property  string  xsNMTOKEN  getset; }
   property  IList<string>  xsNMTOKENS  getset; }
   property  decimal  xsNonNegativeInteger  getset; }
   property  decimal  xsNonPositiveInteger  getset; }
   property  string  xsNormalizedString  getset; }
   property  decimal  xsPositiveInteger  getset; }
   property  System.Xml.XmlQualifiedName  xsQName  getset; }
   property  byte  xsUnsignedByte  getset; }
   property  uint  xsUnsignedInt  getset; }
   property  ulong  xsUnsignedLong  getset; }
   property  ushort  xsUnsignedShort  getset; }
   property  short  xsShort  getset; }
   property  string  xsString  getset; }
   property  System.DateTime  xsTime  getset; }
   property  string  xsToken  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Appendix: Name mapping

Note: This topic is not documented in the current release of LINQ to XSD.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Appendix: Namespace mapping

Note: This topic is not documented in the current release of LINQ to XSD.



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Appendix: More samples

Subsections



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Purchase orders

The following schema is used in the LINQ to XSD overview.

Schema sample

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="Batch">
          <xs:complexType>
               <xs:sequence>
                    <xs:element ref="PurchaseOrder" minOccurs="0" maxOccurs="unbounded"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

     <xs:element name="PurchaseOrder">
          <xs:complexType>
               <xs:sequence>
                    <xs:element name="CustId" type="xs:string"/>

                    <xs:element ref="Item" minOccurs="0" maxOccurs="unbounded"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

     <xs:element name="Item">
          <xs:complexType>
               <xs:sequence>
                    <xs:element name="ProdId" type="xs:string"/>

                    <xs:element name="Price" type="xs:double"/>

                    <xs:element name="Quantity" type="xs:int"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

</xs:schema>

OO API

class Batch : XTypedElement
{
   constructor  Batch();
   explicit cast  Batch(System.Xml.Linq.XElement xe);
   property  IList<PurchaseOrder>  PurchaseOrder  getset; }
}
class PurchaseOrder : XTypedElement
{
   constructor  PurchaseOrder();
   explicit cast  PurchaseOrder(System.Xml.Linq.XElement xe);
   property  string  CustId  getset; }
   property  IList<Item>  Item  getset; }
}
class Item : XTypedElement
{
   constructor  Item();
   explicit cast  Item(System.Xml.Linq.XElement xe);
   property  string  ProdId  getset; }
   property  double  Price  getset; }
   property  int  Quantity  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Invoices for orders

The following schema is used in the XML 2006 paper.

Schema sample

<:schema xmlns:xmlns="http://www.w3.org/2001/XMLSchema">
     <:element name="Invoice">
          <:complexType>
               <:sequence>
                    <:element name="Name" type="string"/>

                    <:element name="Street" type="string"/>

                    <:element name="City" type="string"/>

                    <:element name="Zip" type="string"/>

                    <:element name="State" type="string"/>

                    <:element name="Position" maxOccurs="unbounded">
                         <:complexType>
                              <:sequence>
                                   <:element name="ProdId" type="string"/>

                                   <:element name="Price" type="double"/>

                                   <:element name="Quantity" type="int"/>

                              </:sequence>

                         </:complexType>

                    </:element>

                    <:element name="Total" type="double"/>

               </:sequence>

          </:complexType>

     </:element>

</:schema>

OO API

class Invoice : XTypedElement
{
   constructor  Invoice();
   explicit cast  Invoice(System.Xml.Linq.XElement xe);
   property  string  Name  getset; }
   property  string  Street  getset; }
   property  string  City  getset; }
   property  string  Zip  getset; }
   property  string  State  getset; }
   property  IList<Position>  Position  getset; }
   property  double  Total  getset; }
}
class Position : XTypedElement
{
   constructor  Position();
   explicit cast  Position(System.Xml.Linq.XElement xe);
   property  string  ProdId  getset; }
   property  double  Price  getset; }
   property  int  Quantity  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Company organization

The following schema is used in the LINQ to XSD demo.

Schema sample

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="Company">
          <xs:complexType>
               <xs:sequence>
                    <xs:element ref="Department" minOccurs="0" maxOccurs="unbounded"/>

               </xs:sequence>

          </xs:complexType>

     </xs:element>

     <xs:element name="Department">
          <xs:complexType>
               <xs:sequence>
                    <xs:element name="Label" type="xs:string"/>

                    <xs:element name="Manager" type="EmployeeType" minOccurs="0"/>

                    <xs:element ref="Member" minOccurs="0" maxOccurs="unbounded"/>

               </xs:sequence>

               <xs:attribute name="Deptno" type="xs:int"/>

          </xs:complexType>

     </xs:element>

     <xs:element name="Member">
          <xs:complexType>
               <xs:choice>
                    <xs:element name="Employee" type="EmployeeType"/>

                    <xs:element ref="Department"/>

               </xs:choice>

          </xs:complexType>

     </xs:element>

     <xs:complexType name="EmployeeType">
          <xs:sequence>
               <xs:element name="Name" type="xs:string"/>

               <xs:element name="Salary" type="xs:double"/>

          </xs:sequence>

     </xs:complexType>

</xs:schema>

OO API

class Company : XTypedElement
{
   constructor  Company();
   explicit cast  Company(System.Xml.Linq.XElement xe);
   property  IList<Department>  Department  getset; }
}
class Department : XTypedElement
{
   constructor  Department();
   explicit cast  Department(System.Xml.Linq.XElement xe);
   property  string  Label  getset; }
   property  EmployeeType  Manager  getset; }
   property  IList<Member>  Member  getset; }
   property  int?  Deptno  getset; }
}
class Member : XTypedElement
{
   constructor  Member();
   constructor  Member(EmployeeType Employee);
   constructor  Member(Department Department);
   explicit cast  Member(System.Xml.Linq.XElement xe);
   property  EmployeeType  Employee  getset; }
   property  Department  Department  getset; }
}
class EmployeeType : XTypedElement
{
   constructor  EmployeeType();
   explicit cast  EmployeeType(System.Xml.Linq.XElement xe);
   property  string  Name  getset; }
   property  double  Salary  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.


Language syntax

The following schema is used in the LINQ to XSD demo.

Schema sample

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="Program" type="Block"/>

     <xs:complexType name="Expr" abstract="true"/>

     <xs:complexType name="Constant">
          <xs:complexContent>
               <xs:extension base="Expr">
                    <xs:choice>
                         <xs:element name="Integer" type="xs:int"/>

                         <xs:element name="Boolean" type="xs:boolean"/>

                    </xs:choice>

               </xs:extension>

          </xs:complexContent>

     </xs:complexType>

     <xs:complexType name="Variable">
          <xs:complexContent>
               <xs:extension base="Expr">
                    <xs:sequence>
                         <xs:element name="Id" type="xs:string"/>

                    </xs:sequence>

               </xs:extension>

          </xs:complexContent>

     </xs:complexType>

     <xs:complexType name="Block">
          <xs:complexContent>
               <xs:extension base="Expr">
                    <xs:sequence>
                         <xs:element name="Decl" type="Decl" minOccurs="0" maxOccurs="unbounded"/>

                         <xs:element name="Expr" type="Expr" maxOccurs="unbounded"/>

                    </xs:sequence>

               </xs:extension>

          </xs:complexContent>

     </xs:complexType>

     <xs:complexType name="Decl">
          <xs:sequence>
               <xs:element name="Id" type="xs:string"/>

               <xs:element name="Type" type="Type"/>

          </xs:sequence>

     </xs:complexType>

     <xs:complexType name="Type" abstract="true"/>

     <xs:complexType name="Integer">
          <xs:complexContent>
               <xs:extension base="Type"/>

          </xs:complexContent>

     </xs:complexType>

     <xs:complexType name="Boolean">
          <xs:complexContent>
               <xs:extension base="Type"/>

          </xs:complexContent>

     </xs:complexType>

     <xs:complexType name="Assign">
          <xs:complexContent>
               <xs:extension base="Expr">
                    <xs:sequence>
                         <xs:element name="Id" type="xs:string"/>

                         <xs:element name="Rhs" type="Expr"/>

                    </xs:sequence>

               </xs:extension>

          </xs:complexContent>

     </xs:complexType>

</xs:schema>

OO API

class Expr : XTypedElement
{
   constructor  Expr();
   explicit cast  Expr(System.Xml.Linq.XElement xe);
}
class Constant : Expr
{
   constructor  Constant();
   constructor  Constant(int? Integer);
   constructor  Constant(bool? Boolean);
   explicit cast  Constant(System.Xml.Linq.XElement xe);
   property  int?  Integer  getset; }
   property  bool?  Boolean  getset; }
}
class Variable : Expr
{
   constructor  Variable();
   explicit cast  Variable(System.Xml.Linq.XElement xe);
   property  string  Id  getset; }
}
class Block : Expr
{
   constructor  Block();
   explicit cast  Block(System.Xml.Linq.XElement xe);
   property  IList<Decl>  Decl  getset; }
   property  IList<Expr>  Expr  getset; }
}
class Decl : XTypedElement
{
   constructor  Decl();
   explicit cast  Decl(System.Xml.Linq.XElement xe);
   property  string  Id  getset; }
   property  Type  Type  getset; }
}
class Type : XTypedElement
{
   constructor  Type();
   explicit cast  Type(System.Xml.Linq.XElement xe);
}
class Integer : Type
{
   constructor  Integer();
   explicit cast  Integer(System.Xml.Linq.XElement xe);
}
class Boolean : Type
{
   constructor  Boolean();
   explicit cast  Boolean(System.Xml.Linq.XElement xe);
}
class Assign : Expr
{
   constructor  Assign();
   explicit cast  Assign(System.Xml.Linq.XElement xe);
   property  string  Id  getset; }
   property  Expr  Rhs  getset; }
}
class Program : XTypedElement
{
   constructor  Program();
   constructor  Program(Block content);
   explicit cast  Program(System.Xml.Linq.XElement xe);
   property  Block  Content  get;  }
   property  IList<Decl>  Decl  getset; }
   property  IList<Expr>  Expr  getset; }
}



Copyright (C) 2006-2007 Microsoft Corporation. All rights reserved.