如何从xsd生成.NET 4.0类?

360

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


@drzaus 我以前做过这个工作,但现在当我添加一个时,它生成的是 DataSet 类,而不是我期望的类。我只需添加一个现有项目并选择 XSD 文件即可。 - msmucker0527
11个回答

552

很简单,只需在VS命令提示符下运行:

xsd your.xsd /classes

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

有关选项,请使用 xsd /?参见MSDN;例如,/enableDataBinding 可能很有用。


99
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\xsd.exe" /classes /language:CS your.xsd - GeorgesC
4
Gravell 再次拯救!虽然这个答案是100%正确的,但在我的情况下,我发现将 xsd.exe 目录路径添加到 PATH 环境变量最容易。我的电脑->属性->高级->环境变量->Path——添加"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools"(当然要特别注意你计算机上的 Windows 和 .NET 版本)——愉快编程! - pim
21
如果您有几个相互关联的架构定义,请将它们全部命名。xsd schema1.xsd schema2.xsd schema3.xsd /c - mivra

59

xsd.exe由Marc Gravell提到。在我看来,是最快上手的方式。

或者,如果你需要更多灵活性和选项:

xsd2code VS插件(Codeplex)


10
我无法让xsd2code正常运行,xsd.exe更为健壮,但在处理具有“循环”组的模式时会遇到问题。 - Jeff
xsd2code适用于Visual Studio 2017,正是我一直在寻找的工具。您需要首先在Program Files(x86)目录中运行它,然后使用vsix安装程序。然后它就会非常好地工作。与生成数组[][]而不是列表的xsd.exe相比,它表现得更加出色。我有一个巨大的.xsd文件,需要创建类将XML序列化为类。Xsd.exe无法生成可序列化的代码(.net core 2),而xsd2code却可以很好地完成这个任务。 - hanzolo
1
XSD2CODE的Visual Studio 2015和2017的更新版本已经发布,下载链接在这里:https://marketplace.visualstudio.com/items?itemName=Cestbienmoi.Xsd2Code2015 - Gianpiero
1
原来的xsd2code现在是xsd2code++。社区版可在VS Marketplace上获得(https://marketplace.visualstudio.com/items?itemName=PascalCabanelxsd2codecom.xsd2code5)。 - Gerd K

51
我在这里向您展示使用Vs2017和Vs2019最简单的方法。 用Visual Studio打开你的xsd文件,并按照url中的建议生成一个样本xml文件。
1.一旦你在设计视图中打开了你的xsd,如下所示,点击xml schema explorer。 enter image description here 2.在“XML Schema Explorer”中向下滚动,找到根/数据节点。右键单击根/数据节点,它将显示“Generate Sample XML”。如果没有显示,则说明你不在数据元素节点上,而是在任何数据定义节点上。

enter image description here

  1. 将生成的Xml复制到剪贴板中
  2. 在您的解决方案中创建一个新的空类,并删除类定义。只有名称空间应该保留
  3. 当鼠标指针位于您的类内时,选择编辑->特殊粘贴->将Xml作为类粘贴

2
很遗憾,这并不能保证生成所有的类,但这是一个很酷的技巧。 - John Zabroski
1
@JohnZabroski你有没有遇到过不起作用的情况?这取决于示例xml,如果您可以创建包含所有类和成员的示例xml,则没有理由错过任何类和成员。 - Emil
我的观点是第二步并不保证能够成功。但这确实是一个很酷的技巧。 - John Zabroski
1
精彩的回答。你应该喝几瓶冰啤酒!! - HenryGuillen17
1
简单模式很酷!但如果你有像xs:choice这样的元素,它就没有什么帮助了。 - Pavel Biryukov
太棒了!如果您的解决方案中有其他具有相同名称的类,则在从xml代码生成类时会遇到麻烦。更改节点的名称或使用自定义命名空间。 - César Qüeb

15

为了获得一个快速且简便的解决方案(而且不需要使用VS),可以尝试这些在线转换工具:

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

}

注意!请注意这仅是为了帮助您入门,结果显然需要改进!


非常感谢。这可以作为学习.NET中XML Schema和XML的人们的很好的示例。 - theeranitp
精彩的回答,你值得一些冰啤酒! - HenryGuillen17
是的,但使用Visual Studio或CMD将XSD转换为C#要容易得多:https://qawithexperts.com/article/c-sharp/generate-class-from-xsd-in-c-using-cmd-or-visual-studio/277 - user13993546

14

xsd.exe在存在循环引用时表现不佳(即类型可以直接或间接拥有自己类型的元素)。

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

两者都无法很好地处理选择功能。您将得到对象的列表/集合而不是想要的类型。 如果可能的话,建议避免在xsd中使用choice,因为它不能很好地序列化/反序列化为强类型类。 不过,如果您不介意,那么这不是问题。

xsd2code中的任何功能反序列化为System.Xml.XmlElement,我发现这非常方便,但如果您想要强类型对象,则可能会成为问题。 我经常在允许自定义配置数据时使用any,因此XmlElement方便传递到其他自定义定义的XML反序列化程序。


我通过查看您的答案添加了xsd2code。我们需要更改任何内容以处理循环组引用吗?默认属性对我不起作用。 - Jyotsna Sonawane
我不需要做任何特殊的事情就可以处理循环引用。如果您将XML作为新问题发布并在此处添加链接,我很乐意查看它。 - VoteCoffee

5

我在批处理脚本中使用 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%

5
在我的情况下起作用的命令是:
xsd /c your.xsd 

3

如果您希望使用自动属性生成类,请使用此工具将XSD转换为XML,然后使用此工具将XML转换为JSON,并将结果复制到剪贴板中。 接下来在VS中,在您要创建类的文件中,转到编辑>粘贴特殊>以类形式粘贴JSON。


很棒的答案。在我看来,效果更好了。 - AlanC

2

我在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吧 :-) 我曾经不得不与它们一起工作,再也不会碰它们或者使用亚马逊的XSD文件来做任何C#的工作了,它们太混乱了,简直难以置信。 - shawty
@shawty 我正在处理GIS标准 - WFS和WMS - 这些标准由大型、循环交叉引用的XSD定义。使用xsd.exe时遇到了很多问题,因为它不支持循环引用,但最终我还是成功了。 - Aske B.
是的,那本来是我的第二个猜测。我也见过那些,但它们远没有亚马逊的东西那么糟糕...回想起来就会让我噩梦连连,发抖 - shawty

1
Marc Gravell的答案对我有用,但我的xsd文件扩展名是.xml。当我使用xsd程序时,它会显示:
- The table (Amt) cannot be the child table to itself in nested relations.

根据KB325695的说明,我将扩展名从.xml改为.xsd,然后它就正常工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接