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