代码之家  ›  专栏  ›  技术社区  ›  Scott Chamberlain

如何解析XSD文件

  •  3
  • Scott Chamberlain  · 技术社区  · 15 年前

    我正在编写一个代码生成工具,它将接收从visualstudio的数据集生成器生成的XSD文件,并为每个表中的每一列创建一个自定义类。我已经知道如何实现 IVsSingleFileGenerator multi-file generator . 然而,似乎这一步我有最大的麻烦,是一个应该是最简单的。我以前从未真正使用过XML或xmlschema,我不知道迭代XSD文件并读取列名和类型以便构建代码的正确方法是什么。

    关于如何阅读XSD文件的教程有什么建议吗?还有关于如何拉每一个的建议吗 xs:element msprop:Generator_UserColumnName , type ,和 msprop:Generator_ColumnPropNameInTable 每个元素的属性。

    5 回复  |  直到 15 年前
        1
  •  7
  •   Community Mohan Dere    8 年前

    正如btlog所说,xsd应该被解析为XML文件。C#确实为此提供了功能。

    XPath教程: http://www.w3schools.com/xpath/default.asp
    XQuery教程: http://www.w3schools.com/xquery/default.asp
    XmlDocument http://www.codeproject.com/KB/cpp/myXPath.aspx

    在C#中,XPath/XQuery通过 XmlDocument . 特别是通过打电话 SelectSingleNode SelectNodes .

    我推荐 XML文档 结束 XmlTextReader 如果您的目标是提取特定的数据块。如果你喜欢逐行读, 更合适。

    更新:对于那些对使用Linq查询XML感兴趣的人,介绍了.NET4.0 XDocument 作为替代 XML文档 . 请参阅上的讨论 XDocument or XmlDocument .

        2
  •  10
  •   TMN    15 年前

    您需要创建一个 XmlSchemaSet ,读入模式,然后编译它以创建信息集。完成之后,就可以开始遍历文档了

    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...
                        }
                    }
                }
            }
        }
    }
    

    显然,您希望将所有子处理的内容放在一个单独的方法中,并递归地调用它,但这应该向您展示一般的流程。

        3
  •  2
  •   btlog Stefan Wick MSFT    15 年前

    编辑:

    快速搜索有一个表示模式的System.Xml.Schema.XmlSchema对象,它很可能更适用。 http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschema.aspx 有一个使用这个类的好例子。

        4
  •  0
  •   Icemanind    15 年前

    正如您所知,Visual Studio包含一个名为XSD的工具,它已经获取了一个XSD文件,并为C#或VB.NET生成类: http://msdn.microsoft.com/en-us/library/x6c1kb0s.aspx

        5
  •  0
  •   Carter Medlin    15 年前

    下面是一个如何从生成的XSD文件中获得tableadapters的排序列表的示例。根据数据集是web应用程序还是网站的一部分,XML是不同的。您将需要通读XSD文件以确定您想要读取的内容。希望这能让你开始。

    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