从XML文件创建Schema,类似于VS2010中的Create Schema,并在代码中将XSD转换为类似于xsd.exe的Class

时间:2013-12-17 21:41:35

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

有没有办法使用命令行模拟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>

2 个答案:

答案 0 :(得分:2)

您可以运行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();
        }

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

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

答案 1 :(得分:0)

这是我最终要从.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