Showing posts with label .NET/C#. Show all posts
Showing posts with label .NET/C#. Show all posts

Thursday, August 7, 2008

Generate C# file from XML Schema

To write a serializable C# class file based on an XML Schema is a pain, in case of a complex schema implementation. What if we can have C# class file generated for us? Visual Studio provides us with a tool (XSD.exe) which can do the needful.

Step 1: Go to run and type:

Visual Studio 2005: %comspec% /k ""C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"" x86

Visual Studio 2008: %comspec% /k ""c:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"" x86

This will open up a command prompt window with current directory as "C:\WINDOWS\system32"

Step 2: Navigate to directory where your schema file (.xsd) is. (This step is added for sake of simplicity)

C:\WINDOWS\system32>cd c:\myschema

Step 3: Punch in following line in command prompt

xsd.exe -c -l:c# -n:myNameSpace schema.xsd

This will create a serialized C# class file (.cs) in the same directory as you schema

=================== XSD.exe HELP ============
xsd.exe - Utility to generate schema or class files from given source.
xsd.exe .xsd /classesdataset [/e:] [/l:] [/n:] [/o:] [/s] [/uri:]
xsd.exe .dll.exe [/outputdir:] [/type: [...]]
xsd.exe .xml [/outputdir:]
xsd.exe .xdr [/outputdir:]

- OPTIONS -

/classes
Generate classes for this schema. Short form is '/c'.

/dataset
Generate sub-classed DataSet for this schema. Short form is '/d'.

/enableLinqDataSet
Generate LINQ-enabled sub-classed Dataset for the schemas provided. Short form is '/eld'.

/element:
Element from schema to process. Short form is '/e:'.

/fields
Generate fields instead of properties. Short form is '/f'.

/order
Generate explicit order identifiers on all particle members.

/enableDataBinding
Implement INotifyPropertyChanged interface on all generated types
to enable data binding. Short form is '/edb'.

/language:
The language to use for the generated code. Choose from 'CS', 'VB', 'JS',
'VJS', 'CPP' or provide a fully-qualified name for a class implementing
System.CodeDom.Compiler.CodeDomProvider. The default language
is 'CS' (CSharp). Short form is '/l:'.

/namespace:
The namespace for generated class files. The default namespace
is the global namespace. Short form is '/n:'.

/nologo
Suppresses the banner.

/out:
The output directory to create files in. The default
is the current directory. Short form is '/o:'.

/type:
Type from assembly to generate schema for. Multiple types may be provided.
If no types are provided, then schemas for all types in an assembly
are generated. Short form is '/t:'.

/uri:
Uri of elements from schema to process. Short form is '/u:'.

- ADVANCED -

/parameters:
Read command-line options from the specified xml file. Short form is '/p:'.

=========================================

Friday, August 1, 2008

.Net c# traverse XML Schema (XSD)

Traversing an XML schema using the Schema Object Model (SOM) API provides access to the elements, attributes, and types stored in the SOM.

The following properties of the XmlSchema class provide access to the collection of all global items added to the XML schema.

Property

Object type stored in the collection or array

Elements

XmlSchemaElement

Attributes

XmlSchemaAttribute

AttributeGroups

XmlSchemaAttributeGroup

Groups

XmlSchemaGroup

Includes

XmlSchemaExternal, XmlSchemaInclude, XmlSchemaImport, or XmlSchemaRedefine

Items

XmlSchemaObject (provides access to all global level elements, attributes, and types).

Notations

XmlSchemaNotation

SchemaTypes

XmlSchemaType, XmlSchemaSimpleType, XmlSchemaComplexType

UnhandledAttributes

XmlAttribute (provides access to attributes that do not belong to the schema namespace)

Following is snippet of code I came up with, which works on Schema Object Model (SOM).

// Create a schema collection. In my finding one can only load
// Xml Schema file (schema.xsd) into a XmlSchemaCollection
XmlSchemaCollection myschema = new XmlSchemaCollection();

// loads schema into Schema Collection
myschema.Add("schema namespace", @"C:\schema.xsd");

//Qualified Name comes in handy when one needs to fetch XmlElement from XmlSchema
XmlQualifiedName qn1 = new XmlQualifiedName("elementName", "schema namespace");

//Set the schema type and add the schema to the reader.
foreach (System.Xml.Schema.
XmlSchema schema in myschema)
{
// schema.Elements[qn1] will fetch me desired XmlElement
Console.WriteLine("******************************************");
foreach (
XmlSchemaElement parentElement in schema.Elements.Values)
{
Console.WriteLine("=============================");
Console.WriteLine("ParentElement : " + parentElement.Name);
XmlSchemaComplexType ct = parentElement.ElementType as XmlSchemaComplexType; //Casting to complex type
if (ct != null)
{
if (ct.Attributes!=null)
{
// iterating XmlSchemaObjectCollection for attributes
foreach (
XmlSchemaObject attribute in ct.Attributes)
{
if (attribute.ToString() == "System.Xml.Schema.XmlSchemaAttribute")
{
// bare in mind arrtibute is object of type XmlSchemaObject // casting is required for it to be treated as XmlSchemaAttribute
Console.WriteLine("Attribute: " + ((System.Xml.Schema.
XmlSchemaAttribute)(attribute)).Name);
}
if (attribute.ToString() == "System.Xml.Schema.XmlSchemaAttributeGroupRef")
{
Console.WriteLine("Attribute Group: " + ((System.Xml.Schema.
XmlSchemaAttributeGroupRef)(attribute)).RefName.Name);
}
}
}
XmlSchemaSequence seq = (XmlSchemaSequence)ct.ContentTypeParticle; //Assuming it’s a sequence of elements
foreach (
XmlSchemaParticle p in seq.Items)
{
// if seqence is combination of elements and elementgroups we need to filter "XmlSchemaParticle p" // as we did XmlSchemaAttribute and XmlSchemaAttributeGroupRef
XmlSchemaElement elem = p as XmlSchemaElement; //Check if particle in seq is XmlSchemaElement
if (elem != null)
Console.WriteLine("child: " + elem.QualifiedName.Name.ToString() + " : " + elem.MinOccursString + "," + elem.MaxOccursString);
}
}
}
}

Output on Console : [Click on image to enlarge ]



Hope this helps.

- Cheers