2010-08-20 7 views
3

J'ai un fichier XML que je veux convertir en une liste d'objets POCO.Objet LINQ to XML to POCO

J'ai le code de travail suivant pour lire le XML et créer des objets à partir de celui-ci. Je veux juste vérifier que c'est un bon moyen de le faire et que je ne manque aucun truc. En particulier en ce qui concerne la requête Linq imbriquée.

XDocument xmlDoc = XDocument.Load(path); 
var q = from file in xmlDoc.Descendants("File") 
     select new ImportDefinition() 
     { 
      Name = file.Attribute("Name").Value, 
      TypeName = file.Attribute("TypeName").Value, 
      ColumnMappings = 
      (
       from map in file.Descendants("ColumnMap") 
       select new ColumnMap() 
       { 
        DatabaseColumn = new Column() 
        { 
         Name = map.Element("DatabaseColumn").Attribute("Name").Value 
        } 
       } 
      ).ToList<ColumnMap>()    
     }; 
List<ImportDefinition> def = q.ToList<ImportDefinition>(); 

Merci

Répondre

3

Peut-être essayer une conversion explicite

public class ColumnMap 
{ 
    public static explicit operator ColumnMap(XElement xElem) 
    { 
     return new ColumnMap() 
     { 
      DatabaseColumn = new Column() 
      { 
       Name = xElem.Element("DatabaseColumn").Attribute("Name").Value 
      } 
     }; 
    } 
} 

public class ImportDefinition 
{ 
    public static explicit operator ImportDefinition(XElement xElem) 
    { 
     return new ImportDefinition() 
     { 
      Name   = (string)xElem.Attribute("Name"), 
      TypeName  = (string)xElem.Attribute("TypeName"), 
      Size   = (int)xElem.Attribute("Size"), 
      LastModified = (DateTime?)xElem.Attribute("LastModified"), 
      ColumnMappings = xElem.Descendants("ColumnMap").Select(xelem => (ColumnMap)xelem).ToList() 
     }; 
    } 
} 

utiliser ensuite comme si:

XDocument xmlDoc = XDocument.Load(path); 
List<ImportDefinition> importDefinitions = xmlDoc.Descendants("File").Select(xElem => (ImportDefinition)xElem).ToList() 
+0

AFAIK .Cast <> ne pas invoquer les opérateurs de conversion personnalisés - ou le fait-il? – dtb

+0

@dtb: Si ce n'est pas le cas, cela ne fonctionnera pas. N'a pas testé, mais aurait pensé que c'est juste une extension qui fait quelque chose comme IEnumerable Cast (cibles IEnumerable ) {foreach (cible T dans les cibles) rendement return (U) target; } –

+1

Je crois que c'est exactement ce que fait Enumerable.Cast et ne fonctionnera probablement pas aussi bien à cause de la conversion au paramètre générique 'U' qui ne recherche pas d'opérateurs de conversion personnalisés. Mais je n'ai pas testé aussi bien. – dtb

3

En cas vos objets POCO ne sont pas seulement des propriétés de chaîne, XElement et XAttribute offrent un large choix de conversion operators à d'autres types, y compris nullables en cas l'élément/attribut n'existe pas.

Exemple:

XDocument xmlDoc = XDocument.Load(path); 
var q = from file in xmlDoc.Descendants("File") 
     select new ImportDefinition() 
     { 
      Name   = (string)file.Attribute("Name"), 
      TypeName  = (string)file.Attribute("TypeName"), 
      Size   = (int)file.Attribute("Size"), 
      LastModified = (DateTime?)file.Attribute("LastModified"), 
      // ... 
     };