Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse a XSD file

Tags:

c#

parsing

xsd

I am writing a code generation tool that will take in a XSD file generated from Visual Studio's Data Set Generator and create a custom class for each column in each table. I already understand how to implement a IVsSingleFileGenerator to do the code generation and how to turn that single file generator in to a multi-file generator. However it seems the step I am having the most trouble with is the one that should be the most simple. I have never really worked with XML or XML-Schema before and I have no clue what is the correct way to iterate through a XSD file and read out the column names and types so I can build my code.

Any recommendation on a tutorial on how to read a XSD file? Also any recommendations on how to pull each xs:element that represents a column out and read its msprop:Generator_UserColumnName, type, and msprop:Generator_ColumnPropNameInTable properties from each element.

like image 646
Scott Chamberlain Avatar asked Dec 01 '22 05:12

Scott Chamberlain


1 Answers

You'll want to create an XmlSchemaSet, read in your schema and then compile it to create an infoset. Once you've done that, you can start iterating through the document

XmlSchemaElement root = _schema.Items[0] as XmlSchemaElement;
XmlSchemaSequence children = ((XmlSchemaComplexType)root.ElementSchemaType).ContentTypeParticle as XmlSchemaSequence;
foreach(XmlSchemaObject child in children.Items.OfType<XmlSchemaElement>()) {
    XmlSchemaComplexType type = child.ElementSchemaType as XmlSchemaComplexType;
    if(type == null) {
        // It's a simple type, no sub-elements.
    } else {
        if(type.Attributes.Count > 0) {
            // Handle declared attributes -- use type.AttributeUsers for inherited ones
        }
        XmlSchemaSequence grandchildren = type.ContentTypeParticle as XmlSchemaSequence;
        if(grandchildren != null) {
            foreach(XmlSchemaObject xso in grandchildren.Items) {
                if(xso.GetType().Equals(typeof(XmlSchemaElement))) {
                    // Do something with an element.
                } else if(xso.GetType().Equals(typeof(XmlSchemaSequence))) {
                    // Iterate across the sequence.
                } else if(xso.GetType().Equals(typeof(XmlSchemaAny))) {
                    // Good luck with this one!
                } else if(xso.GetType().Equals(typeof(XmlSchemaChoice))) {
                    foreach(XmlSchemaObject o in ((XmlSchemaChoice)xso).Items) {
                        // Rinse, repeat...
                    }
                }
            }
        }
    }
}

Obviously you'll want to put all the child handling stuff in a separate method and call it recursively, but this should show you the general flow.

like image 60
TMN Avatar answered Dec 04 '22 22:12

TMN