Click here to Skip to main content
15,860,844 members
Articles / Programming Languages / XML
Article

Parsing XSD Schema with SOM

Rate me:
Please Sign up or sign in to vote.
5.00/5 (9 votes)
13 Oct 2008CPOL 73.5K   1.3K   25   14
Pull metadata from a schema or generate XML mappers
HelloSOM.png

Introduction

This article shows how to use a Schema Object Model(SOM) navigator as an arbitrary schema. This is useful when you have a schema and want to generate your own mapping or want to build a custom XML generator or XSD based code generator.

Using the Code

First read schema and "compile", this will validate the schema.

C#
private static XmlSchema
ReadAndCompileSchema(string fileName)
{
    XmlTextReader tr = new XmlTextReader(fileName,
                        new NameTable());

    // The Read method will throw errors encountered
    // on parsing the schema
    XmlSchema schema = XmlSchema.Read(tr,
           new ValidationEventHandler(ValidationCallbackOne));
    tr.Close();

    XmlSchemaSet xset = new XmlSchemaSet();
    xset.Add(schema);

    xset.ValidationEventHandler += new ValidationEventHandler(ValidationCallbackOne);

    // The Compile method will throw errors
    // encountered on compiling the schema
    xset.Compile();

    return schema;
}

private static void ValidationCallbackOne(object sender, ValidationEventArgs args)
{
    Console.WriteLine("Exception Severity: " + args.Severity);
    Console.WriteLine(args.Message);
}

Start traversing at the highest level...

C#
private static void TraverseSOM(string xsfFilename)
{
    XmlSchema custSchema = ReadAndCompileSchema(xsfFilename);

    foreach (XmlSchemaElement elem in
					 custSchema.Elements.Values)
    {
        ProcessElement(elem);
    }
}

Only an element can contain attributes... so it's handled in a little special way:

C#
private static void ProcessElement(XmlSchemaElement elem)
{
    Console.WriteLine("Element: {0}", elem.Name);

    if (elem.ElementSchemaType is XmlSchemaComplexType)
    {
	XmlSchemaComplexType ct = 
		elem.ElementSchemaType as XmlSchemaComplexType;

	foreach (DictionaryEntry obj in ct.AttributeUses)
		Console.WriteLine("Attribute: {0}  ", 
		(obj.Value as XmlSchemaAttribute).Name);

	ProcessSchemaObject(ct.ContentTypeParticle);
    }
}

Process the Choice & Sequence elements generically (this handles the type casting required):

C#
private static void ProcessSequence(XmlSchemaSequence sequence)
{
    Console.WriteLine("Sequence");
    ProcessItemCollection(sequence.Items);
}

private static void ProcessChoice(XmlSchemaChoice choice)
{
    Console.WriteLine("Choice");
    ProcessItemCollection(choice.Items);
}

The Schema objects are processed generically, but uniformly:

C#
private static void ProcessItemCollection(XmlSchemaObjectCollection objs)
{
    foreach (XmlSchemaObject obj in objs)
    ProcessSchemaObject(obj);
}

private static void ProcessSchemaObject(XmlSchemaObject obj)
{
    if (obj is XmlSchemaElement)
        ProcessElement(obj as XmlSchemaElement);
    if (obj is XmlSchemaChoice)
        ProcessChoice(obj as XmlSchemaChoice);
    if (obj is XmlSchemaSequence)
        ProcessSequence(obj as XmlSchemaSequence);
}

Points of Interest

There's a lot of type checking and casting. That's inherent in the data model used in the SOM. It's not a strongly typed data structure. So you have to check, cast, then use. It would be an interesting exercise to generate a strongly typed XSD model, but I'll leave that for another article.

History

  • 2008-10-10: Article created

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer Big Company
United States United States
My professional career began as a developer fixing bugs on Microsoft Word97 and I've been fixing bad habits ever since. Now I do R&D work writing v1 line of business applications mostly in C#/.Net.

I've been an avid pilot/instructor for 13+ years, I've built two airplanes and mostly fly gliders now for fun. I commute in an all-electric 1986 BMW 325 conversion.

I'd like to get back to my academic roots of programming 3D analysis applications to organize complex systems.

Comments and Discussions

 
QuestionLinqToXsd Update Pin
CodingBruce6-May-12 2:31
CodingBruce6-May-12 2:31 
QuestionThanks a lot! Pin
Daniel Leykauf18-Mar-12 12:50
Daniel Leykauf18-Mar-12 12:50 
Questionparsing XSD schema Pin
zinazsh22-Nov-11 11:06
zinazsh22-Nov-11 11:06 
AnswerRe: parsing XSD schema Pin
CodingBruce23-Nov-11 1:23
CodingBruce23-Nov-11 1:23 
QuestionLinq2Xsd makes this silly Pin
CodingBruce23-Sep-11 13:38
CodingBruce23-Sep-11 13:38 
GeneralThe lights go on... Pin
Ger Hayden6-Jun-11 21:09
Ger Hayden6-Jun-11 21:09 
QuestionHow to extract Description that is within annotation tag?Please help! [modified] Pin
abhinavchowdhary18-May-11 10:58
abhinavchowdhary18-May-11 10:58 
AnswerRe: How to extract Description that is within annotation tag?Please help! [modified] Pin
RayD23-Sep-11 13:25
RayD23-Sep-11 13:25 
QuestionProblem with nested <xs:group> Pin
akothoor12-Apr-11 5:38
akothoor12-Apr-11 5:38 
GeneralSchema w/LinqToXsd Pin
CodingBruce4-Dec-10 10:07
CodingBruce4-Dec-10 10:07 
Generalthanks Pin
Member 112416822-Jun-09 0:25
Member 112416822-Jun-09 0:25 
good example
GeneralThank you Pin
Member 238152731-May-09 20:16
Member 238152731-May-09 20:16 
GeneralThanks Pin
John Irwin29-Oct-08 1:26
John Irwin29-Oct-08 1:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.