2010-12-01 6 views
0

Je suis en train de créer une collection d'objets métier à partir du document XML suivant en utilisant .net 4.0/C#Comment puis-je créer une collection d'objets métier à partir de plusieurs éléments dans un XmlDocument

<WebServices ErrorFound="False" ServerDateTime="30/11/2010 14:58:58"> 
     <Results> 
      <Users TotalResults="5"> 
       <UserName UserID="2">John</UserName> 
       <UserName UserID="3">Dave</UserName> 
       <UserName UserID="4">Jim</UserName> 
       <UserName UserID="5">Bob</UserName> 
      </Users> 
     </Results> 
    </WebServices> 

C'est la La classe I doit créer

public class User 
    { 
     public string Name { get; set; } 
     public int ID { get; set; } 
    } 

Chaque élément enfant Users doit être une nouvelle instance de la classe. Jusqu'ici j'ai cette méthode qui accepte un XmlDocument.

public static IEnumerable<User> GetUser(XmlDocument xmlDoc) 
{ 
    XmlReader reader = XmlReader.Create(new StringReader(xmlDoc.OuterXml)); 
    XDocument doc = XDocument.Load(reader); 

    var user = from u in doc.Descendants("WebServices").DescendantsAndSelf("Users") 
       select new User() 
       { 
        Name = u.Element("UserName").Value, 
        ID = int.Parse(u.Element("UserName").Attribute("UserID").Value) 
       }; 

    List<User> userInstance = user.ToList(); 
    IEnumerable<User> users= from u in userInstance 
           select u; 
    return users; 

} 

Cela fonctionne bien pour autant que la production d'une instance de l'objet du premier élément enfant est concerné, mais je ne suis pas certain de la façon de créer plusieurs instances de tous les éléments. Je dois être en mesure de retourner une collection d'objets Utilisateur par exemple Collection<User> users = new Collection<User>()

Je pourrais aboyer complètement le mauvais arbre. Toute aide est très appréciée.

+0

Veuillez ne pas utiliser 'new XmlTextReader()'. Il est obsolète depuis .NET 2.0. Utilisez 'XmlReader.Create()' à la place. –

+0

Merci, méthode mise à jour pour utiliser XmlTextReader(). – Howdy

+0

Performance sage: n'utilisez pas OuterXml, puis un analyseur. Cela écrit le document entier dans un texte, puis l'analyse à nouveau - très cher. Si vous avez vraiment besoin de convertir XmlDocument en XDocument, vous pouvez utiliser par exemple CreateNavigator(). ReadSubtree() pour obtenir un XmlReader sur XmlDocument et l'utiliser pour charger le XDocument. En général, je n'essaierais pas d'utiliser XDocument ou LINQ en XML si l'entrée est XmlDocument, à la place j'utiliserais directement l'API XmlDocument ou XPath pour faire de même et éviter la conversion. –

Répondre

1

Ok, donc j'ai finalement compris ce qui était erroné avec mon code. Au lieu de

var user = from u in doc.Descendants("WebServices").DescendantsAndSelf("Users") 
     select new User() 
     { 
      Name = u.Element("UserName").Value, 
      ID = int.Parse(u.Element("UserName").Attribute("UserID").Value) 
     }; 

J'ai maintenant

var user = (from u in doc.Descendants("UserName") 
     select new Provider() 
     { 
      Name = u.Value, 
      ID = int.Parse(u.Attribute("UserID").Value) 
     }); 

la déclaration: doc.Descendants("UserName") produit essentiellement un tableau des éléments UserName qui peuvent être itérés, je peux alors accéder directement à la valeur de cet élément et définir à mes propriétés de classe.

1

Utilisation de XPath vous pouvez écrire le code comme ceci:

public class User 
{ 
    public string Name { get; set; } 
    public int ID { get; set; } 
} 

static void Main(string[] args) 
{ 
    string xml = 
     "<WebServices ErrorFound='False' ServerDateTime='30/11/2010 14:58:58'>" + 
      "<Results>" + 
       "<Users TotalResults='5'>" + 
        "<UserName UserID='2'>John</UserName>" + 
        "<UserName UserID='3'>Dave</UserName>" + 
        "<UserName UserID='4'>Jim</UserName>" + 
        "<UserName UserID='5'>Bob</UserName>" + 
        "</Users>" + 
      "</Results>" + 
     "</WebServices>"; 

    XmlDocument doc = new XmlDocument(); 
    doc.LoadXml(xml); 

    var users = from userNameElement in doc.SelectNodes("/WebServices/Results/Users/UserName").OfType<XmlElement>() 
       select new User 
       { 
        Name = userNameElement.InnerText, 
        ID = Int32.Parse(userNameElement.GetAttribute("UserID")) 
       }; 

    foreach (var user in users) 
    { 
     Console.WriteLine(user.ID.ToString() + ": " + user.Name); 
    } 
} 
+0

Merci, c'est aussi une option. – Howdy

Questions connexes