Comment générer des classes .NET 4.0 à partir de xsd?

317

Quelles sont les options pour générer des classes (entités) c .NET 4.0 à partir d'un fichier xsd, à l'aide de Visual Studio 2010?

Bastien Vandamme
la source
@drzaus J'ai eu ce travail dans le passé, mais maintenant, quand j'en ajoute un, il génère en tant que classe DataSet au lieu des classes auxquelles je m'attendais. Je viens d'ajouter un élément existant et de sélectionner le fichier XSD.
msmucker0527

Réponses:

490

assez simple; il suffit d'exécuter (à l'invite de commande vs)

xsd your.xsd /classes

(qui va créer your.cs). Notez, cependant, que la plupart des options intrinsèques ici n'ont pas beaucoup changé depuis 2.0

Pour les options, utilisez xsd /?ou consultez MSDN ; par exemple, /enableDataBindingpeut être utile.

Marc Gravell
la source
83
"C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v8.1A \ bin \ NETFX 4.5.1 Tools \ xsd.exe" / classes / langage: CS your.xsd
GeorgesC
2
Gravell à nouveau à la rescousse! Bien que cette réponse soit correcte à 100%, dans mon cas, j'ai trouvé plus facile d'ajouter le chemin du répertoire xsd.exe à la variable d'environnement PATH. Mon ordinateur -> propriétés -> avancées -> variables d'environnement -> Chemin d'accès - et ajoutez "C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v8.1A \ bin \ NETFX 4.5.1 Tools \" (bien sûr attention aux versions Windows et .NET spécifiques à votre machine) - codage heureux!
pimbrouwers
15
Dans le cas où vous avez plusieurs définitions de schéma interconnectées, nommez-les toutes. xsd schema1.xsd schema2.xsd schema3.xsd /c
mivra
56

xsd.exe comme mentionné par Marc Gravell. Le moyen le plus rapide de devenir opérationnel avec l'OMI.

Ou si vous avez besoin de plus de flexibilité / d'options:

Complément VS x2code VS (Codeplex)

Serge Wautier
la source
10
Je ne pouvais pas du tout faire fonctionner xsd2code pour moi. xsd.exe est plus robuste, mais a du mal avec les schémas qui ont des groupes "circulaires".
Jeff
xsd2code fonctionne dans Visual Studio 2017 et était exactement ce que je cherchais. vous devez d'abord l'exécuter dans le répertoire des fichiers programme (x86), puis utiliser le programme d'installation vsix. alors ça marche très bien. c'était LARGE SUPÉRIEUR au xsd.exe qui a généré des tableaux [] [] au lieu de lists.i avait un géant .xsd et j'ai besoin de créer des classes pour sérialiser le XML en. xsd.exe ne générerait pas de code sérialisable (.net core 2) et xsd2code fonctionnait très bien
hanzolo
La version mise à jour de XSD2CODE pour Visual Studio 2015 e 2017 est ici: marketplace.visualstudio.com/…
Gianpiero
Le xsd2code d'origine est désormais xsd2code ++. L'édition communautaire est disponible sur VS Marketplace
Gerd K
17

Je vous montre ici la manière la plus simple d'utiliser Vs2017 et Vs2019 Ouvrez votre xsd avec Visual Studio et générez un exemple de fichier xml comme dans l' url suggérée.

  1. Une fois que vous avez ouvert votre xsd en mode création comme ci-dessous, cliquez sur xml schema explorer entrez la description de l'image ici

2. Dans «XML Schema Explorer», faites défiler vers le bas pour trouver le nœud racine / données. Cliquez avec le bouton droit sur le nœud racine / données et il affichera «Générer un échantillon XML». S'il ne s'affiche pas, cela signifie que vous n'êtes pas sur le nœud d'élément de données mais que vous êtes sur l'un des nœuds de définition de données.

entrez la description de l'image ici

  1. Copiez votre XML généré dans le presse-papiers
  2. Créez une nouvelle classe vide dans votre solution et supprimez la définition de classe. Seul l'espace de noms doit rester
  3. Pendant que le pointeur de votre souris se concentre sur votre classe, choisissez EDIT-> Paste Special-> Paste Xml as Classes
batmaci
la source
Ce n'est pas garanti de générer toutes les classes, malheureusement, mais c'est une astuce COOL.
John Zabroski
1
@JohnZabroski avez-vous eu des cas où cela n'a pas fonctionné pour vous? Cela dépend de l'exemple de XML, si vous pouvez créer un exemple de XML avec toutes les classes et tous les membres, il n'y a aucune raison de manquer une classe et un membre.
batmaci
Mon point est que l'étape 2 n'est pas garantie de fonctionner. Mais c'est une astuce COOL.
John Zabroski
Magnifique réponse. Vous méritez des bières froides !!
HenryGuillen17
14

xsd.exe ne fonctionne pas bien lorsque vous avez des références circulaires (c'est-à-dire qu'un type peut posséder un élément de son propre type directement ou indirectement).

Lorsque des références circulaires existent, j'utilise Xsd2Code. Xsd2Code gère bien les références circulaires et fonctionne dans VS IDE, ce qui est un gros plus. Il possède également de nombreuses fonctionnalités que vous pouvez utiliser, comme la génération du code de sérialisation / désérialisation. Assurez-vous d'activer GenerateXMLAttributes si vous générez la sérialisation (sinon vous obtiendrez des exceptions pour la commande si elles ne sont pas définies sur tous les éléments).

Aucun ne fonctionne bien avec la fonction de choix. vous vous retrouverez avec des listes / collections d'objets au lieu du type que vous souhaitez. Je recommanderais d'éviter le choix dans votre xsd si possible car cela ne sérialise pas / désérialise bien dans une classe fortement typée. Si vous ne vous souciez pas de cela, cependant, ce n'est pas un problème.

Toute fonctionnalité de xsd2code se désérialise en System.Xml.XmlElement que je trouve vraiment pratique mais qui peut être un problème si vous voulez des objets typés forts. J'en utilise souvent quand j'autorise des données de configuration personnalisées, donc un XmlElement est pratique à passer à un autre désérialiseur XML qui est personnalisé ailleurs.

VoteCoffee
la source
J'ai ajouté xsd2code en regardant votre réponse. Faut-il changer quoi que ce soit pour qu'il prenne en charge les références de groupe circulaires? Cela ne fonctionne pas pour moi avec les propriétés par défaut
Jyotsna Sonawane
Je n'avais rien à faire de spécial pour que cela fonctionne avec des références circulaires. Si vous postez le xml en tant que nouvelle question et ajoutez un lien ici, je suis heureux de l'examiner.
VoteCoffee
10

Pour une solution rapide et paresseuse (et sans utiliser VS du tout), essayez ces convertisseurs en ligne:

  • Convertisseur xsd en xml ici
  • Convertisseur xmltocsharp ici

XSD => XML => classes C #

Exemple 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>

Convertit en 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>

Qui se convertit dans cette structure de classe:

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

}

Attention! Prenez en compte qu'il ne s'agit que de Get-You-Started, les résultats ont évidemment besoin d'être affinés!

cnom
la source
Merci beaucoup. Cela peut être utilisé comme un bon exemple pour ceux qui apprennent le schéma XML et XML dans .NET
theeranitp
Magnifique réponse. Vous méritez des bières froides!
HenryGuillen17
5

J'utilise XSDdans un script batch pour générer directement des .xsdfichiers et des classes XML:

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%
hdoghmen
la source
2

La commande qui a fonctionné dans mon cas était:

xsd /c your.xsd 
Melchia
la source
1

La réponse de Marc Gravells était bonne pour moi mais mon xsd l'était avec l'extension .xml. Quand j'ai utilisé le programme xsd, cela a donné:
- The table (Amt) cannot be the child table to itself in nested relations.

Selon ce KB325695, j'ai renommé l'extension de .xml en .xsd et cela a bien fonctionné.

Igoris Azanovas
la source
1

J'ai utilisé xsd.exedans l'invite de commande Windows.

Cependant, comme mon xml faisait référence à plusieurs xml en ligne (dans mon cas, http://www.w3.org/1999/xlink.xsdqui fait référence http://www.w3.org/2001/xml.xsd), je devais également télécharger ces schémas, les mettre dans le même répertoire que mon xsd, puis lister ces fichiers dans la commande:

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

Aske B.
la source
Ce ne serait pas le marché Amazon XSD où vous construisez des classes pour le moment :-) J'ai dû travailler avec eux une fois, plus jamais je ne les toucherai ou ne ferai aucun travail en C # en utilisant des fichiers XSD amazon, il y a un tel gâchis c'est irréel.
shawty
@shawty Je travaillais avec les normes SIG - WFS et WMS - qui sont définies par de grands XSD circulaires avec références croisées. C'était un gros gâchis xsd.exeparce qu'il n'aime pas les références circulaires, mais j'ai réussi à la fin.
Aske B.
oui, cela aurait été ma deuxième supposition. Vu ceux-là aussi, leur nulle part aussi mauvais que les trucs des Amazones ... me donne des cauchemars qui se souviennent des frissons
shawty
0

Avec WSDL, j'avais des fichiers xsd. Ce qui précède n'a pas fonctionné dans mon cas a donné une erreur. Cela a fonctionné comme suit

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