【问题标题】:Create Schema from XML file similar to Create Schema in VS2010 and convert XSD to Class similar to xsd.exe, in code从类似于 VS2010 中的 Create Schema 的 XML 文件创建 Schema 并将 XSD 转换为类似于 xsd.exe 的类,在代码中
【发布时间】:2014-01-30 21:53:44
【问题描述】:

有没有办法通过 xsd.exe 使用命令行来模拟在 Visual Studio 中单击 XML 选项卡下的“创建架构”选项时会发生什么?

我正在尝试自动化从 XML 创建模式的过程,以便使用 XSD 创建类。

当我使用 xsd file.xml 命令时出现错误:无法添加名为“MyXMLElement”的列:同名的嵌套表已属于此 DataTable。但是,当我在 VS2010 中使用 Create Schema 选项时,它工作正常。

<Person xmlns="http://someNamespace/1.0" xmlns:j="http://www.google.com/2.0" xmlns:nc="http://yahoo.com/3.0">   
    <MainElement>
        <j:FirstElement>
            <nc:SecondElement>
                <nc:Value>something.com</nc:Value>
            </nc:SecondElement>
        </j:FirstElement>
        <nc:FirstElement>
            <ThirdElement>          
                <nc:PersonName>
                    <nc:Value>SomeName</nc:Value>
                </nc:PersonName>
            </ThirdElement>
        </nc:FirstElement>
    </MainElement>
</Person>

【问题讨论】:

    标签: xml visual-studio-2010 xsd xsd.exe


    【解决方案1】:

    您可以运行xsd.exe file.xml,它应该会生成file.xsd,即实例文档的架构。

    我尝试了您编辑的示例并遇到了同样的错误。我认为这种方法有效,但似乎我错了。作为替代方案,.NET 有 System.Xml.Schema.XmlSchemaInference 类,我已经测试过它不会引发错误:

            XmlSchemaInference xs = new XmlSchemaInference();
            XmlSchemaSet schemaSet;
    
            using (XmlReader xr = XmlReader.Create("file.xml"))
            {
                schemaSet = xs.InferSchema(xr);
            }
    
            foreach (XmlSchema schema in schemaSet.Schemas())
            {
                Console.WriteLine(schema.TargetNamespace);
                schema.Write(Console.Out);
                Console.WriteLine();
            }
    

    当然,您可以将它们保存到文件中,而不是将用于测试的模式写入控制台。有一个问题,在我对您的文件的测试中,在模式集中创建了三个模式,每个目标命名空间一个,主要的一个,例如&lt;xs:import namespace="http://www.google.com/2.0" /&gt; 导入其他的,但由于没有文件,schema.Write 不输出任何位置。

    这就是我目前所能提出的全部建议,我意识到这不是一个完整的解决方案,但也许它可以帮助您解决问题。

    【讨论】:

    • 当我使用该命令时出现错误:无法添加名为“MyXMLElement”的列:同名的嵌套表已属于此 DataTable。但是,当我在 VS2010 中使用 Create Schema 选项时它工作正常
    • 您是否对.xml 文件使用该命令?该错误听起来好像您运行 xsd.exe 以生成数据集..
    • @Sanpopo,您能否发布一个最小但完整的.xml 文档,在执行xsd.exe file.xml 时给出此错误?我不确定问题出在哪里,所以我需要查看一个允许我重现问题的示例。
    • 错误是由两个同名但命名空间不同的 xml 节点引起的。所以我会有&lt;nc:MyXMLElement&gt;&lt;j:MyXMLElement&gt; 我在主要问题中添加了一个示例。
    • @Sanpopo,我已经编辑了答案,可能使用 .NET 框架类库提供的XmlSchemaInference 有帮助。
    【解决方案2】:

    这就是我最终从 .xml 文件创建 XSD,然后将 XSD 转换为一个或多个类并保存该类文件的操作。

    Imports System
    Imports System.IO
    Imports System.Runtime.Serialization
    Imports System.Xml
    Imports System.Xml.Schema
    Imports System.Xml.Serialization
    Imports System.CodeDom
    Imports System.CodeDom.Compiler
    
    Public Class XMLToClass
        Implements IXMLToClass
    
        Public Sub New()
        End Sub
    
        Public Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType Implements IXMLToClass.GetDataUsingDataContract
    
            Return composite
        End Function
    
    
    
        Public Sub GenerateClassFromXML(ByVal XMLfileName As String, ByVal OutPutFilePath As String, ByVal CodeNameSpace As String)
            Dim xs As New XmlSchemaInference()
            Dim schemaSet As XmlSchemaSet
            Dim schemas As New XmlSchemas()
            Using xr As XmlReader = XmlReader.Create(XMLfileName)
                xs.TypeInference = XmlSchemaInference.InferenceOption.Relaxed
                xs.Occurrence = XmlSchemaInference.InferenceOption.Relaxed
                schemaSet = xs.InferSchema(xr)
            End Using
    
            For Each Schema As XmlSchema In schemaSet.Schemas
                schemas.Add(Schema)
            Next
            PersistClass(schemas, OutPutFilePath, CodeNameSpace)
    
        End Sub
    
        Public Sub PersistClass(ByVal schemas As XmlSchemas, ByVal OutPutFileName As String, ByVal namesp As String)
    
            ' Get the namespace for the schema.
            Dim ns As CodeNamespace = XsdGenerator.Processor.Process(schemas, namesp)
            ' Create the appropriate generator for the language.
            Dim provider As CodeDomProvider
            provider = New Microsoft.VisualBasic.VBCodeProvider()
            ' Write the code to the output file.
            Using sw As New StreamWriter(OutPutFileName, False)
                provider.GenerateCodeFromNamespace(ns, sw, New CodeGeneratorOptions())
            End Using
    
        End Sub
    End Class
    
    Namespace XsdGenerator
        Public NotInheritable Class Processor
            Public Shared Function Process(ByVal schemas As XmlSchemas, targetNamespace As String) As CodeNamespace
    
                ' Create the importer for these schemas.
                Dim importer As New XmlSchemaImporter(schemas)
                ' System.CodeDom namespace for the XmlCodeExporter to put classes in.
                Dim ns As New CodeNamespace(targetNamespace)
                Dim exporter As New XmlCodeExporter(ns)
                ' Iterate schema top-level elements and export code for each.
                For Each xsd As XmlSchema In schemas
                    For Each element As XmlSchemaElement In xsd.Elements.Values
                        ' Import the mapping first.
                        Dim mapping As XmlTypeMapping = importer.ImportTypeMapping(element.QualifiedName)
                        ' Export the code finally.
                        exporter.ExportTypeMapping(mapping)
                    Next
                Next
    
                Return ns
            End Function
        End Class
    End Namespace
    

    【讨论】:

      猜你喜欢
      • 2019-07-22
      • 1970-01-01
      • 2012-08-27
      • 2020-03-26
      • 1970-01-01
      • 2013-01-11
      • 2012-08-22
      • 2021-12-20
      • 2012-03-16
      相关资源
      最近更新 更多