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

4 comments:

Sachin Gaur said...

its great feature.. i really won't have any idea that .NET has such feature. Keep publishing this kind of things.

Sachin Gaur said...

Hi Sandepp, It would be great help for me if you could specify any XML file format that can be used to convert C# file.

Sandeep said...

Hi Sachin,

C# file is generated based on input XML schema. I would recommend you to create an XML schema and then use xsd.exe (tool provided by Visual Studio 2005/2008) to generate serialized c# file.
For further details please refer my post: http://dwell-deeper.blogspot.com/2008/08/generate-c-file-cs-from-xml-schema-xsd.html

st.Jhimy said...

maybe it help:
http://www.stjhimy.com/2009/10/17/playing-around-with-xmls-and-xsds-net-smiles-for-you/