Remplir une sous-classe List personnalisée à partir d’un document XML via LINQ

J’ai compris comment renseigner une classe personnalisée à partir de données XML, mais j’ai rencontré un problème en cours de route. Les choses fonctionnaient parfaitement avec ma méthode existante de peuplement de données jusqu’à ce que je sois lancé dans une boule courbe. Le nouveau schéma qui m’a été envoyé ressemble à ceci:

 1320691307345 0 8.2784   001134 USA 47.000 EA   006817 USA 20.000 EA      

Joli schéma XML standard, le problème est que je ne sais pas comment remplir ma classe personnalisée avec. Voici ce que j’ai

 static void Main(ssortingng[] args) { var order = ConvertXMLMessage(request); } protected static T ConvertXMLMessage(Ssortingng xmlData) where T : class, new() { var xml = new XmlDocument(); xml.LoadXml(xmlData); var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); using (var xmlReader = new XmlNodeReader(xml.DocumentElement)) { T work = (T)(serializer.Deserialize(xmlReader)); return work; } } public class ItemReply { [XmlElement("ITEM_REPLY")] public ItemAvlReply ITEM_REPLY { get; set; } } public class ItemAvlReply { [XmlElement("TRAN_ID")] public ssortingng TRAN_ID { get; set; } [XmlElement("REPLY_CODE")] public ssortingng REPLY_CODE { get; set; } [XmlElement("UNIT_PRICE")] public ssortingng UNIT_PRICE { get; set; } [XmlElement("SUP_LOCS")] public SupplierLocations SUP_LOCS; [XmlElement("MESSAGE")] public ssortingng MESSAGE { get; set; } [XmlElement("QTY_BREAKS")] public ssortingng QTY_BREAKS { get; set; } } public class SupplierLocations { [XmlElement("SUP_LOC")] public List SUP_LOC; } public class SupplierLocation { [XmlElement("SUP_LOC_ID")] public ssortingng SUP_LOC_ID { get; set; } [XmlElement("COUNTRY_ID")] public ssortingng COUNTRY_ID { get; set; } [XmlElement("QTY_AVL")] public ssortingng QTY_AVL { get; set; } [XmlElement("ITEM_UOM")] public ssortingng ITEM_UOM { get; set; } } 

Cela fonctionne parfaitement moins la partie List . Je ne suis pas trop familiarisé avec LINQ et je ne sais pas trop comment déclarer un sous-tableau dans ma classe via cette instruction. Je suis également ouvert à une approche différente de la création de la partie List . Je ne sais pas par où commencer autrement. Y a-t-il une meilleure approche pour ce que je dois faire? Existe-t-il une solution facile que je ne connais pas dans LINQ?

Voici un moyen simple de le faire, en supposant que l’exemple de fichier XML que vous avez fourni comporte des fautes de frappe. J’ai supposé que OrderId avait une balise de fermeture et que la balise de fermeture des Items devrait être /Items .

Voici la version du XML que j’ai utilisée:

  123 1   Test Red   Test1 Blue    

Voici le code pour lire / écrire le XML: (la variable xml est une chaîne)

 var order = ConvertXMLMessage(xml); WriteXMLFile(order, @"test.xml"); 

Voici les fonctions ConvertXMLMessage et WriteXMLFile:

 protected static T ConvertXMLMessage(Ssortingng xmlData) where T : class, new() { var xml = new XmlDocument(); xml.LoadXml(xmlData); var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); using (var xmlReader = new XmlNodeReader(xml.DocumentElement)) { T work = (T)(serializer.Deserialize(xmlReader)); return work; } } protected static void WriteXMLFile(T item, Ssortingng saveLocation) where T : class, new() { System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(typeof(T)); System.IO.StreamWriter file = new System.IO.StreamWriter(saveLocation); writer.Serialize(file, item); file.Close(); } 

et voici la structure de classe:

 public class Order { [XmlElement("TransactionID")] public ssortingng TransactionId { get; set; } [XmlElement("OrderID")] public ssortingng OrderId { get; set; } [XmlElement("Items")] public ItemsContainer Items; } public class ItemsContainer { [XmlAtsortingbute("Number")] public Int32 Number { get; set; } [XmlElement("Item")] public List Items; } public class Item { [XmlElement("ItemName")] public ssortingng ItemName { get; set; } [XmlElement("Color")] public ssortingng Color { get; set; } } 

Comme vous le remarquerez, j’ai ajouté quelques atsortingbuts pour que l’parsingur XML sache comment gérer la classe lors de la conversion de / vers XML. J’ai également ajouté une autre petite classe appelée “ItemsContainer” qui contient uniquement les détails de la balise Items. Si vous n’avez pas besoin de l’atsortingbut “Number”, vous pourrez probablement trouver un moyen de vous en passer. Cependant, cela devrait vous amener dans la bonne direction.

L’exemple que j’ai fourni est une version simple de la façon dont je gère habituellement la situation. Évidemment, vous pouvez apporter certaines améliorations en fonction de vos besoins.

Modifier J’ai modifié la classe Item afin d’utiliser ItemName au lieu de TransactionId . C’était un oubli de ma part.

Éditer 2 Voici les corrections que vous devez apporter au code nouvellement posté. La raison pour laquelle la classe Order fonctionné dans l’exemple précédent était qu’elle correspondait à l’élément XML racine. Votre nouveau XML est aligné avec la classe de base. Nous devons donc append quelques atsortingbuts supplémentaires pour que cela fonctionne. Vous pouvez également supprimer votre classe ItemReply . Ce n’est pas nécessaire.

Alors voici les nouvelles classes:

 [XmlRoot("ITEM_REPLY")] public class ItemAvlReply { [XmlElement("TRAN_ID")] public ssortingng TRAN_ID { get; set; } [XmlElement("REPLY_CODE")] public ssortingng REPLY_CODE { get; set; } [XmlElement("UNIT_PRICE")] public ssortingng UNIT_PRICE { get; set; } [XmlElement("SUP_LOCS")] public SupplierLocations SUP_LOCS; [XmlElement("MESSAGE")] public ssortingng MESSAGE { get; set; } [XmlElement("QTY_BREAKS")] public ssortingng QTY_BREAKS { get; set; } } public class SupplierLocations { [XmlElement("SUP_LOC")] public List SUP_LOC; } public class SupplierLocation { [XmlElement("SUP_LOC_ID")] public ssortingng SUP_LOC_ID { get; set; } [XmlElement("COUNTRY_ID")] public ssortingng COUNTRY_ID { get; set; } [XmlElement("QTY_AVL")] public ssortingng QTY_AVL { get; set; } [XmlElement("ITEM_UOM")] public ssortingng ITEM_UOM { get; set; } } 

Tout le rest devrait restr le même. L’parsing / conversion du XML en classes devrait fonctionner sans aucune modification.