如何从 xsd 生成 .NET 4.0 类?

Posted

技术标签:

【中文标题】如何从 xsd 生成 .NET 4.0 类?【英文标题】:How to generate .NET 4.0 classes from xsd? 【发布时间】:2011-07-10 05:08:19 【问题描述】:

使用 Visual Studio 2010 从 xsd 文件生成 .NET 4.0 c# 类(实体)的选项有哪些?

【问题讨论】:

@drzaus 我过去做过这项工作,但现在当我添加一个时,它会生成为 DataSet 类,而不是我期望的类。我只是添加一个现有项目并选择 XSD 文件。 【参考方案1】:

足够简单;只需运行(在 vs 命令提示符下)

xsd your.xsd /classes

(这将创建your.cs)。但是请注意,这里的大多数内在选项自 2.0 以来并没有太大变化

对于选项,使用xsd /? 或see MSDN;例如/enableDataBinding 可能很有用。

【讨论】:

"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\xsd.exe" /classes /language:CS your.xsd跨度> 格拉维尔再次救援!虽然这个答案是 100% 正确的,但在我的情况下,我发现将 xsd.exe 目录路径添加到 PATH 环境变量是最简单的。我的电脑 -> 属性 -> 高级 -> 环境变量 -> 路径 - 并添加“C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\”(当然密切注意特定于您的机器的 Windows 和 .NET 版本)——祝您编码愉快! 如果您有多个相互关联的模式定义,只需将它们全部命名即可。 xsd schema1.xsd schema2.xsd schema3.xsd /c【参考方案2】:

Marc Gravell 提到的 xsd.exe。启动和运行 IMO 的最快方法。

或者,如果您需要更多的灵活性/选项:

xsd2code VS 插件(Codeplex)

【讨论】:

我根本无法让 xsd2code 为我工作。 xsd.exe 更健壮,但与具有“循环”组的模式比较困难。 xsd2code 在 Visual Studio 2017 中工作,正是我想要的。您必须首先在程序文件 (x86) 目录中运行它,然后使用 vsix 安装程序。然后效果很好。它远优于生成数组 [] [] 而不是列表的 xsd.exe。我有一个巨大的 .xsd,我需要创建类来将 XML 序列化为。 xsd.exe 不会生成可序列化代码(.net core 2)并且 xsd2code 工作得很好 Visual Studio 2015 e 2017 的 XSD2CODE 更新版本在这里:marketplace.visualstudio.com/… 原来的 xsd2code 现在是 xsd2code++。社区版是available on VS Marketplace【参考方案3】:

我在这里向您展示使用 Vs2017 和 Vs2019 的最简单方法 使用 Visual Studio 打开您的 xsd 并生成一个示例 xml 文件,如 url 建议的那样。

    在如下设计视图中打开 xsd 后,单击 xml 架构资源管理器

2。 在“XML Schema Explorer”中一直向下滚动以找到根/数据节点。右键单击根/数据节点,它将显示“生成示例 XML”。如果未显示,则表示您不在数据元素节点上,而是在任何数据定义节点上。

    将生成的 Xml 复制到剪贴板中 在您的解决方案中创建一个新的空类并删除该类定义。只有命名空间应该保留 当您的鼠标指针聚焦在您的类中时,选择编辑-> 选择性粘贴-> 将 Xml 粘贴为类

【讨论】:

不幸的是,这不能保证生成所有类,但它是一个很酷的技巧。 @JohnZabroski 您是否有任何情况表明它对您不起作用?这取决于示例 xml,如果您可以创建包含所有类和成员的示例 xml,那么没有理由错过任何类和成员。 我的意思是第 2 步不能保证有效。但这是一个很酷的技巧。 精彩的答案。你应该喝点冰镇啤酒!! 很酷的简单模式!但如果你有元素行 也无济于事【参考方案4】:

当你有循环引用时,xsd.exe 不能很好地工作(即一个类型可以直接或间接拥有它自己类型的元素)。

当存在循环引用时,我使用 Xsd2Code。 Xsd2Code 可以很好地处理循环引用并在 VS IDE 中工作,这是一个很大的优势。它还具有许多您可以使用的功能,例如生成序列化/反序列化代码。如果您正在生成序列化,请确保打开 GenerateXMLAttributes(否则,如果未在所有元素上定义,您将获得排序异常)。

两者都不适用于选择功能。你最终会得到对象的列表/集合,而不是你想要的类型。如果可能,我建议避免在您的 xsd 中进行选择,因为这不能很好地序列化/反序列化为强类型类。但是,如果您不关心这一点,那么这不是问题。

xsd2code 中的 any 功能反序列化为 System.Xml.XmlElement,我觉得这很方便,但如果您想要强类型对象,这可能是个问题。在允许自定义配置数据时,我经常使用 any,因此 XmlElement 可以方便地传递给另一个在其他地方自定义定义的 XML 反序列化器。

【讨论】:

我通过查看您的答案添加了 xsd2code。我们是否需要对其进行任何更改以处理循环组引用?默认属性对我不起作用 我不需要做任何特别的事情来处理循环引用。如果您将 xml 作为新问题发布并在此处添加链接,我很乐意查看。【参考方案5】:

对于快速而懒惰的解决方案,(并且根本不使用 VS)试试这些在线转换器:

xsd 到 xml 转换器here xmltocsharp 转换器here

XSD => XML => C# 类

XSD 示例:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="shiporder">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="orderperson" type="xs:string"/>
      <xs:element name="shipto">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="address" type="xs:string"/>
            <xs:element name="city" type="xs:string"/>
            <xs:element name="country" type="xs:string"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="item" maxOccurs="unbounded">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="title" type="xs:string"/>
            <xs:element name="note" type="xs:string" minOccurs="0"/>
            <xs:element name="quantity" type="xs:positiveInteger"/>
            <xs:element name="price" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="orderid" type="xs:string" use="required"/>
  </xs:complexType>
</xs:element>

</xs:schema>

转换为 XML:

<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Technologies Online Tools 1.0 (https://www.liquid-technologies.com) -->
<shiporder xsi:noNamespaceSchemaLocation="schema.xsd" orderid="string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <orderperson>string</orderperson>
  <shipto>
    <name>string</name>
    <address>string</address>
    <city>string</city>
    <country>string</country>
  </shipto>
  <item>
    <title>string</title>
    <note>string</note>
    <quantity>3229484693</quantity>
    <price>-6894.465094196054907</price>
  </item>
  <item>
    <title>string</title>
    <note>string</note>
    <quantity>2181272155</quantity>
    <price>-2645.585094196054907</price>
  </item>
  <item>
    <title>string</title>
    <note>string</note>
    <quantity>2485046602</quantity>
    <price>4023.034905803945093</price>
  </item>
  <item>
    <title>string</title>
    <note>string</note>
    <quantity>1342091380</quantity>
    <price>-810.825094196054907</price>
  </item>
</shiporder>

转换为此类结构:

   /* 
    Licensed under the Apache License, Version 2.0

    http://www.apache.org/licenses/LICENSE-2.0
    */
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp

    [XmlRoot(ElementName="shipto")]
    public class Shipto 
        [XmlElement(ElementName="name")]
        public string Name  get; set; 
        [XmlElement(ElementName="address")]
        public string Address  get; set; 
        [XmlElement(ElementName="city")]
        public string City  get; set; 
        [XmlElement(ElementName="country")]
        public string Country  get; set; 
    

    [XmlRoot(ElementName="item")]
    public class Item 
        [XmlElement(ElementName="title")]
        public string Title  get; set; 
        [XmlElement(ElementName="note")]
        public string Note  get; set; 
        [XmlElement(ElementName="quantity")]
        public string Quantity  get; set; 
        [XmlElement(ElementName="price")]
        public string Price  get; set; 
    

    [XmlRoot(ElementName="shiporder")]
    public class Shiporder 
        [XmlElement(ElementName="orderperson")]
        public string Orderperson  get; set; 
        [XmlElement(ElementName="shipto")]
        public Shipto Shipto  get; set; 
        [XmlElement(ElementName="item")]
        public List<Item> Item  get; set; 
        [XmlAttribute(AttributeName="noNamespaceSchemaLocation", Namespace="http://www.w3.org/2001/XMLSchema-instance")]
        public string NoNamespaceSchemaLocation  get; set; 
        [XmlAttribute(AttributeName="orderid")]
        public string Orderid  get; set; 
        [XmlAttribute(AttributeName="xsi", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Xsi  get; set; 
    


注意!考虑到这只是入门,结果显然需要改进!

【讨论】:

非常感谢。对于那些正在学习 XML Schema 和 .NET 中的 XML 的人来说,这可以作为一个很好的例子 精彩的答案。你应该喝点冰镇啤酒!【参考方案6】:

我在批处理脚本中使用XSD 直接从XML 生成.xsd 文件和类:

set XmlFilename=Your__Xml__Here
set WorkingFolder=Your__Xml__Path_Here

set XmlExtension=.xml
set XsdExtension=.xsd

set XSD="C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1\Tools\xsd.exe"

set XmlFilePath=%WorkingFolder%%XmlFilename%%XmlExtension%
set XsdFilePath=%WorkingFolder%%XmlFilename%%XsdExtension%

%XSD% %XmlFilePath% /out:%WorkingFolder%
%XSD% %XsdFilePath% /c /out:%WorkingFolder%

【讨论】:

【参考方案7】:

在我的案例中有效的命令是:

xsd /c your.xsd 

【讨论】:

【参考方案8】:

Marc Gravells 的回答对我来说是正确的,但我的 xsd 的扩展名为 .xml。当我使用 xsd 程序时,它给出了:- The table (Amt) cannot be the child table to itself in nested relations.

根据KB325695,我将扩展名从 .xml 重命名为 .xsd 并且效果很好。

【讨论】:

【参考方案9】:

我在 Windows 命令提示符中使用了xsd.exe

但是,由于我的 xml 引用了几个在线 xml(在我的情况下 http://www.w3.org/1999/xlink.xsd 引用了 http://www.w3.org/2001/xml.xsd),我还必须下载这些原理图,将它们放在与我的 xsd 相同的目录中,然后在命令:

"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\xsd.exe" /classes /language:CS your.xsd xlink.xsd xml.xsd

【讨论】:

那不会是亚马逊市场 XSD 的你现在在那里建立课程吧 :-) 我不得不和他们一起工作一次,我再也不会碰他们或做任何工作C#使用amazons XSD文件,乱七八糟的不真实。 @shawty 我正在使用 GIS 标准——WFS 和 WMS——它们是由大型圆形交叉引用 XSD 定义的。 xsd.exe 很乱,因为它不喜欢循环引用,但我最终成功了。 是的,那是我的第二个猜测。也看到了这些,尽管它们没有亚马逊的东西那么糟糕......让我想起颤抖的噩梦【参考方案10】:

除了 WSDL,我还有 xsd 文件。以上在我的情况下不起作用给出了错误。它的工作原理如下

wsdl /l:C# /out:D:\FileName.cs D:\NameApi\wsdl_1_1\RESAdapterService.wsdl 
D:\CXTypes.xsd D:\CTypes.xsd 
D:\Preferences.xsd 

【讨论】:

【参考方案11】:

如果要生成具有自动属性的类,请使用 this 将 XSD 转换为 XML,然后使用 this 将 XML 转换为 JSON,并将结果复制到剪贴板。 然后在 VS 中,在将创建类的文件中,转到编辑>选择性粘贴>将 JSON 粘贴为类。

【讨论】:

很棒的答案。工作得更好,IMO。

以上是关于如何从 xsd 生成 .NET 4.0 类?的主要内容,如果未能解决你的问题,请参考以下文章

如何将外部xsd导入另一个xsd?

从 Visual Studio 中的类生成 XSD

如何从现有的 WSDL 和 XSD 文件生成 WCF 服务主机

是否可以使用 Qt(不使用 XSD 工具)从 xsd 生成 C++ 类?

如何从 wsdl 生成 xsd

VB中使用XSD生成的类读取XML示例