2009-09-14 5 views
11

J'ai un fichier xml plutôt détaillé. Ci-dessous le nœuds de haut niveau (j'ai inclus l'ellipse comme les nœuds de niveau inférieur sont tous bien formés et correctement rempli de données):Problème avec la désérialisation XML dans les classes générées par XSD

<?xml version="1.0" encoding="UTF-8"?> 
<config> 
    <Models>...</Models> 
    <Data>...</Data> 
</config> 

J'ai créé un fichier XSD d'utiliser l'invite de commande Visual Studio 2008:

xsd sample.xml 

Cela génère le fichier xsd très bien. Je puis cours Générer automatiquement de la xsd avec la commande:

xsd sample.xsd /classes 

Pour la désérialisation du fichier XML dans un objet de classe, j'utilise la fonction de lecture dans la classe d'aide:

public class XmlSerializerHelper<T> 
{ 
    public Type _type; 

    public XmlSerializerHelper() 
    { 
     _type = typeof(T); 
    } 

    public void Save(string path, object obj) 
    { 
     using (TextWriter textWriter = new StreamWriter(path)) 
     { 
      XmlSerializer serializer = new XmlSerializer(_type); 
      serializer.Serialize(textWriter, obj); 
     } 
    } 

    public T Read(string path) 
    { 
     T result; 
     using (TextReader textReader = new StreamReader(path)) 
     { 
      XmlSerializer deserializer = new XmlSerializer(_type); 
      result = (T)deserializer.Deserialize(textReader); 
     } 
     return result; 
    } 
} 

lors d'une tentative de la désérialisation avec:

var helper = new XmlSerializerHelper<configModels>(); 
var obj = new configModels(); 
obj = helper.Read(filepath); 

Je reçois une erreur que j'ai déduit est parce que le désérialiseur est à la recherche pour le nœud « modèles » mais le nom de la classe correspondante était generat ed en tant que combinaison du noeud racine et du noeud 'Modèle' (configModels). Pourquoi les noms des classes sont-ils générés comme ça?

J'ai essayé de désérialiser à partir du nœud supérieur à l'aide:

var helper = new XmlSerializerHelper<config>(); 
var obj = new config(); 
obj = helper.Read(filepath); 

Malheureusement, cela les résultats dans une série d'erreurs comme ce qui suit:

System.InvalidOperationException was unhandled by user code 
Message="Unable to generate a temporary class (result=1). 
error CS0030: Cannot convert type 'Application.Lease[]' to 'Application.Lease' 
error CS0030: Cannot convert type 'Application.CashFlow[]' to 'Application.CashFlow' 
...ect. 

Quelqu'un peut-il me diriger vers ce que je pourrais avoir mal avec mon xsd auto-générer?

+0

Aucun des outils automatisés ne produirait le code correct. J'ai écrit à la main le code objet pour le xml à désérialiser en. –

+0

Pourriez-vous s'il vous plaît marquer la réponse de marc_s comme correcte puisque vous avez dit qu'il a résolu votre problème? – Win

Répondre

3

Il existe un problème avec xsd.exe et les listes. Vous devez aller dans la classe générée et éditer manuellement le fichier dans le bon type. Je suis passé à l'utilisation de Xsd2Code. Jusqu'à présent, il ne semble pas avoir ce problème.

+0

J'ai juste essayé Xsd2Code et il me donne aussi les mêmes erreurs de conversion avec les listes. –

+0

Ne dois-je pas utiliser xsd.exe pour générer automatiquement le fichier xsd? –

+0

Vous pouvez l'utiliser très bien. Vous devez simplement aller dans la classe générée et l'éditer à la main. Cependant, si Xsd2Code avait aussi des problèmes, je serais d'accord avec @marc_s; c'est probablement quelque chose dans votre schéma XML qui cause le problème. –

10

XSD.EXE est un bon début - mais c'est loin d'être parfait. En outre, basé sur le code XML que vous avez fourni, XSD.EXE ne peut pas toujours décider avec certitude si quelque chose est une instance unique d'un objet ou un tableau d'objets à extrémité ouverte.

Cela semble être le cas pour vos deux éléments - Application.Lease et Application.CashFlow. Comment sont-ils définis dans le fichier XSD généré? Est-ce que cela a du sens pour vous? Très probablement, il faudrait ajouter un peu des conseils, tels que:

<xs:element name="Lease" minOccurs="0" maxOccurs="1" /> 

pour une propriété en option, qui est zéro ou un occurences seulement. Des choses comme ça sont vraiment difficiles à comprendre pour l'outil xsd.exe basé sur un seul fichier d'exemple XML.

Marc

+1

Marc, vous avez raison sur l'argent là-bas, votre solution a résolu le problème pour moi. La mise à jour manuelle des valeurs minOccurs et maxOccurs sur les éléments incriminés, puis l'exécution de XSD2CODE pour générer mes classes ont résolu ce problème pour moi. – ProNotion

10

Accédez à votre classe générée et changer tout de [] [] ---> []

+0

Bien que cela résoudra le problème, la réponse de marc_s explique pourquoi cela est nécessaire et comment éviter d'avoir à faire cela. – MyItchyChin

0

Une autre question qui peut causer ce problème est que le contenu du fichier xml entre les balises (ce qui signifie le contenu) est toujours codé quand il ne devrait pas être. Par exemple, les balises <br> dans mon contenu étaient toujours <br> au lieu de &lt;br /&gt;. Le générateur xsd les a transformés en éléments dans le schéma puis les a mal étiquetés comme illimités car il y en avait plus d'un.Unencoding les a résolu le problème et a généré les classes correctement.

Questions connexes