Introduction
Click Here to Download The Code Sample for this Article.
The W3C XML Schema recommendation has been adopted as a standard in much of the XML world to describe the structure and content of an XML document. For authors unfamiliar with writing XML schemas from scratch, there is often the need to be able to generate an XML schema from a given XML document. Many tools in the Microsoft .NET Framework, such as the xsd.exe in the .NET Framework SDK, the ADO.NET DataSet, and the Inference class in the System.XML.Schema namespace of the. NET Framework 2.0 Beta 1, Provide the Ability, Given A Sample XML Document, To Infer A Schema. However, Not Many Tools Exist, on Microsoft Platforms, Which Generate A Sample XML Document from a Given Schema.
This article will describe a tool that can generate an XML document given a schema, and assumes that the reader is familiar with the W3C XML Schema specification Such a tool can be useful for many purposes:. To design the schema progressively by looking at the generated Instance, To Generate Random Sample Consume XML, AND Other Such Scenarios. This Tool is AIMED AT The Former Case: in-schema design Scenarios.
Note The Code Sample for this article................
Goals of the xml generator
To generate an XML sample that is easy to read and illustrates the use of various constructs in the given XML Schema. The generated document should be valid with respect to the schema. If validity can not be achieved, it should be signaled by adding comments to .
Overview of the xmlsamplegenerator apiconstructors
There Are Three Construction Overloads That Can Be Used To Create The XmlsampleGenerator:
An Overload Takes The Schema File Name and The Qualified Name of The Root Element of The XML Document. Public XmlsampleGenerator (String Url, XmlqualifiedName Rootelem)
An Overload Takes An Xmlschema Object and The Qualified Name of The Root Element of The XML Document. Public XmlsampleGenerator (Xmlschema Schema, XmlqualifiedName Rootelem)
An Overload Takes An Xmlschemaset Object and The Qualified Name of The Root Element of The XML Document. Public XmlsampleGenerator (Xmlschemaset Schemaset, XmlqualifiedName Rootelem)
..........................
PROPERTIES
There Are Three Properties Exposed on The XmlsampleGenerator:
XmlResolver-public XmlResolver XmlResolver {set;} Using this property, users can set their custom resolver, and this will be used in loading the import / include / redefine schemaLocations in the XmlSchemaSet The XmlUrlResolver is used by default MaxThreshold-public int MaxThreshold.. {get; set;} This property overrides the value of the maxOccurs attribute in the schema If maxOccurs = "100" or maxOccurs = "unbounded" appears in an element, setting this property to 10 will generate that element 10 times The default.. Value for this property is 5. listLength-public int ListLength {get; set;} this property defines how much iple type of variety List. The default value of this property is 3.
Methods
WriteXml-public void WriteXml (XmlWriter writer) The WriteXml () method takes an XmlWriter that is used to write the generated XML. Since this takes an XmlWriter, users can write the XML to their store or to a file.
The Following Is A Simple PurchaseOrder Schema, with a Top-Level PurchaseOrder Element That Has Two Child Elements, Shipto and Billto, And One Attribute, ORDERDATE.
Po.xsd:
xsd: sequence>
xsd: complexType>
xsd: sequence>
xsd: complexType>
xsd: schema>
THE FOLLOWING CODE WILL GENERATE The Po.xml Instance That Conforms To The Above Schema.xmlTextWriter TextWriter = New XMLTextWriter ("Po.xml", NULL);
TextWriter.Formatting = formatting.indented;
XmlqualifiedName Qname = new xmlqualifiedname ("purchaseorder",
"http://tempuri.org");
XmlsampleGenerator generator = New XmlsampleGnelerator ("Po.xsd", QNAME);
Genr.WriteXml (TextWriter);
The generated document is shown below.
Po.xml:
Shipto>
Shipto>
BillTo>
Purchaseorder>
NUTS AND BOLTS of The XmlsampleGenerator
The XmlSchemaSet class (this replaces the XmlSchemaCollection in .NET Framework 2.0) is used as the in-memory schema cache to load and compile schemas. Once the schemas are loaded into the schema set and compiled, the XML is generated by walking the content model Of Each Element Beginning at the root element.
Corresponding to the schema tree that begins at the root element that is specified by the user, an instance tree is generated by walking the Schema Object Model The nodes in the instance tree are annotated with additional information (for example:. Whether the element node has a default or a fixed value) that is useful while actually writing the XML using the XmlWriter. The instance tree is created by applying the rules specified below while traversing the content model.Content Model Generation
Mixed Content: if Mixed = true, THEN A TEXT Node with value text will be generated as the first child of the element. Sequence, choice, all:
Every child of a sequence is generated based on its minOccurs / maxOccurs, and the sequence itself will be repeated based on the min / max of the sequence. The value specified through the MaxThreshold property overrides the maxOccurs specified in the schema. If the choice occurs only once, then the first particle within the choice is generated; otherwise we cyclically iterate over all the children in the choice The generation of xs: all is similar to that of a sequence, except that the elements are generated in the reverse order,. as order does not matter for xs:. all wildcards: All element wildcards are mapped to an XmlSchemaElement by locating an element in the schema set's GlobalElements table if it satisfies the namespace constraint of the.
Value generation
Simple type values are generated by creating a value generator for the corresponding datatype of the element or attribute. The value generator is aware of any facets declared on the simple type and will generate values that will be valid according to the type's facets. The XmlSampleGenerator supports All facets except the xs: pattern facet.the Tool supports all datatypes defined in w3c xmlschema datatypes except xs: entity, xs: enttive and xs: notation.
The Following Rules Are Applied While Generating Values:
Values of type xs: string are generated by appending the element name with a numeric counter The length of such a generated string is modified based on the presence of Length, minLength, and maxLength facets Values of specific string-derived types like xs..: NCName, xs: token, and others, have the type name appended with a numeric counter to differentiate them from xs:.. string numeric values are generated by selecting values between the maximum and minimum values for the corresponding CLR type Every type has an associated default start value (for example, the start value is 1 for xs: integer and 1900-01-01 for xs: date) that is modified based on the presence of certain facets like minInclusive, minExclusive, and so on If the element or. Attribute Has A Default Value, That Is Used in The Generation As The First Value. If The Element OR Attribute Has A Fixed Value, ONLY THIS VALUE IS USED IN The Generation.
Working with the xmlsamplegenerator
Now let us generate some sample XML instances from schemas to illustrate that the generated instances will conform to various features in W3C XML Schema, like facet restrictions, abstract types, substitution groups, and wildcards.
Facet Restrictions
Let's change the type of the Zip element from xs: integer to ZipIntType, a restriction of xs: integer with minInclusive and MaxExclusive values; the type of the Street element in USAddress to streetType, a restriction of xs: string with minLength = 13; and The Type of The State Element in Usaddress to StateType, An Enumeration of 5 US State Codes.
xsd: restriction>
xsd: SimpleType>
xsd: restriction>
xsd: SimpleType>
xsd: restriction>
xsd: SimpleType>
Now the value for the zip, street, and state elements will be generated aciding to the new facet restrictions introduces.
Shipto>
Shipto>
BillTo>
Purchaseorder>
SIMPLETYPE LISTS
The XML Schema has the concept of a list type, where a list is a sequence of atomic values. This allows for an element or an attribute value to be one or more instances of one atomic type. The tool will generate, by default, 3 Values of the itemtype for an element or attribute whose, the listley generator can be be set so as to change this default value.
To our purchaseorder schema, let us add an element items which holds the list of items to be shipped as part of this order.
xsd: complexType>
xsd: restriction>
xsd: SimpleType>
xsd: list>
xsd: SimpleType>
The following xml is generated for the above schema.
Shipto>
Shipto>
BillTo>
Purchaseorder>
Union Types
The XML Schema provides the xs: union construct to allow for an element or attribute value to be an instance of any one type drawn from a union of multiple atomic or list types The types that form the union are called the memberTypes of the union.. for an element or attribute whose type is a union type, our tool will cyclically iterate over each memberType in the union to generate the values. to illustrate this, let us use the example in the W3C XML Schema Primer of a ZipUnion type for our Zip Element.
xsd: SimpleType>
NOTIP Element Alternate Between The StateType and The zipinttype in the xml generated below.
Shipto>
Shipto>
BillTo>
Purchaseorder> Abstract Types
Abstract types are complex types with abstract = "true" defined in the schema, to allow for substitution of more specific types in the XML instance by using the xsi:. Type attribute When an element's type is declared to be abstract, the element's content can not .
In the purchase order schema above, if we want a common address type with the element's Name, Street, and City, and a more specific type for US addresses where we can constrain the State values and the Zip values, we can define the common address Type to Be Abstract and Derive The US Address Type from this Abstract Type.
Let us change from usaddress to addresstype, and let addrestype be Abstract as shown bellow.
xsd: sequence>
xsd: complexType>
xsd: sequence>
xsd: complexType>
xsd: sequence>
xsd: extension>
xsd: complexContent>
xsd: complexType>
.
Shipto>
Shipto>
BillTo>
Purchaseorder>
Substitution Groups
Substitution groups provide a mechanism that is provided by the XML Schema to allow substituting an element in the schema with another in the instance. One or more elements can be marked as being substitutable for a global element (also called the head element), which means that members of this substitution group are interchangeable with the head element in a content model. The only requirement is that the members of the substitution group must be of the same type or be in the same type hierarchy as the head element.While generating content models ...................... ..
Let us add an element called Details to the PurchaseOrderType to include more details about the order itself. The Details element is abstract, and ShipDetails and BillDetails are member elements of the substitutionGroup headed by the Details element.
SubstitutionGroup = "TNS: Details" /> SubstitutionGroup = "TNS: Details" /> xsd: sequence> xsd: complexType> xsd: complexType> xsd: complexType> For Every Occurrence of It Details Element, One Member of Its SubstitutionGroup Is Chosen to Be Generated In The Instance. ... Shipto> ... Shipto> ... BillTo> Purchaseorder> Wildcards xs: any and xs: anyAttribute are the wildcards provided in the W3C XML Schema to allow elements and attributes from specified namespaces to appear in the XML instance The namespace and processContents attributes provide some control to the schema author in constraining the occurrence of open content. . .. The Following Table Lists How Elements / Attributes Will Be Generated Corresponding To The Wildcards Decland. processContentsNamespaceGenerated element Generated AttributeSkip or lax ## any, ## targetNamespace If, as an author of the purchase order schema, we would like to allow for occurrence of elements and attributes from other custom namespaces in the instances that we will process, we should add an xs: any and xs: anyAttribute to the purchaseOrderType with namespace = "## taher". xsd: sequence> xsd: complexType> The xs: anyattribute. As The ProcessContents of the As The ProcessContents on the xs: annattribute is strict, and no valid attribute can be matched, a comment indicating the same is generated as shown beelow. ... Shipto> ... Shipto> ... BillTo> Purchaseorder> Limitations of the xmlsamplegenerator The W3C XML Schema Identity Constraints (xs: key, xs: keyref, xs: unique) are not supported while generating an instance document If xs:. Pattern facets exist on simple types, values generated may not conform to the pattern Enumerations of the. xs: QName type may not work as expected since this requires the prefixes in the schema to be preserved xs:. ENTITY, xs: ENTITIES, and xs: NOTATION types are not supported xs:. base64Binary content is generated only if enumerations exist in the Schema for what type.conclusion ......................... It should also provide an introduction to some of the new schema API in the .NET Framework 2.0 Beta 1: TypeCode and Variety properties on XmlSchemaDatatype, for example The former returns the current type's built-in type, eliminating the need to chain backwards in. The Type Hierarchy, And The Latter Returns WHether The Type is atomic, List, or Union. This sample also includes a command line utility, XmlGen.exe, which enables you to perform command line XML generation using the XmlSampleGenerator library. This utility generates an XML file called "Sample.xml" in the current directory.