开发者

How to parse a XSD file

开发者 https://www.devze.com 2023-01-07 10:18 出处:网络
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

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 co开发者_如何转开发rrect 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.


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.


As btlog says, XSDs should be parsed as XML files. C# does provide functionality for this.

XPath Tutorial: http://www.w3schools.com/xpath/default.asp
XQuery Tutorial: http://www.w3schools.com/xquery/default.asp
Random C# XmlDocument tutorial: http://www.codeproject.com/KB/cpp/myXPath.aspx

In C#, XPath/XQuery are used via XmlDocument . In particular, through calls like SelectSingleNode and SelectNodes.

I recommend XmlDocument over XmlTextReader if your goal is to pull out specific chunks of data. If you prefer to read it line by line, XmlTextReader is more appropriate.

Update: For those interested in using Linq to query XML, .Net 4.0 introduced XDocument as an alternative to XmlDocument. See discussion at XDocument or XmlDocument.


You could just load it into and XmlDocument. Xsd is valid Xml, so if you are familiar with this type it is pretty simple. Alteratively XmlTextReader.

EDIT:

Having a quick search there is a System.Xml.Schema.XmlSchema object that represents a schema, which is most likely more applicable. http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschema.aspx has a good example of using this class.


Just so you know too, Visual Studio includes a tool called XSD that will already take an XSD file and generate classes for either C# or VB.NET: http://msdn.microsoft.com/en-us/library/x6c1kb0s.aspx


Here is an example of how to get a sorted list of the tableadapters from a generated XSD file. The XML is different depending on if the dataset is part of a web application or a web site. You will need to read through the XSD file to determine exactly what you want to read. Hopefully this will get you started.

Dim XMLDoc As New System.Xml.XmlDocument

XMLDoc.Load("MyDataset.xsd")
Dim oSortedTableAdapters As New Collections.Generic.SortedDictionary(Of String, Xml.XmlElement)

Const WebApplication As Boolean = False

Dim TableAdapters = XMLDoc.GetElementsByTagName("TableAdapter")
For Each TableAdapter As Xml.XmlElement In TableAdapters
    If WebApplication Then
        'pre-compiled way'
        oSortedTableAdapters.Add(TableAdapter.Attributes("GeneratorDataComponentClassName").Value, TableAdapter)
    Else
        'dynamic compiled way'
        oSortedTableAdapters.Add(TableAdapter.Attributes("Name").Value, TableAdapter)
    End If
Next
0

精彩评论

暂无评论...
验证码 换一张
取 消