2011-06-08 3 views
1

J'ai un fichier xml comme suit:LINQ to XML: la création d'un type anonyme complexe

<ProductGroup> 
    <Product id="4601A"> 
    <name>Roses</name> 
    <section>Floral</section> 
    <price>46</price> 
    <PopupImages> 
     <PopupImage>img1.jpg</PopupImage> 
     <PopupImage>img2.jpg</PopupImage> 
    </PopupImages> 
    <ImageThumbs> 
     <thumb>img1-thm.jpg</thumb> 
     <thumb>img2-thm.jpg</thumb> 
    </ImageThumbs> 
    </Product> 
</ProductGroup> 

Dans la production du noeud ProductGroup peut contenir plusieurs nœuds de produit. Pour cela, je veux genre de construire une liste d'un objet anonyme qui a les propriétés suivantes:

name 
section 
image 
thumb 

Je suis en mesure d'obtenir une liste des éléments produits à l'aide XDocument.

Dim doc As XDocument = XDocument.Load("ProductsGroups.xml") 
Dim lstProducts = from x In doc Where CType(c.Element("price"), Integer) < 54 

D'où puis-je faire?

Mise à jour:

Laissez-moi vous expliquer cela mieux. Je ne suis pas sûr si j'ai communiqué cela correctement. Prendre l'exemple xml ci-dessus lui-même.

Le code ci-dessus que j'ai écrit retourne tous les éléments du produit avec la condition "where" spécifiée. Maintenant, pour chaque XmlElement renvoyé (produit) Je dois créer un nombre n d'objets anonymes. Le nombre n dépend du nombre d'enfants présents pour les nœuds PopupImages et ImageThumbs. Dans mon cas cependant, le nombre sera le même. il va donc revenir à l'exemple ci-dessus, je reçois deux objets anonymes:

 Anonymous1  Anonymous2 
     ----------  ---------- 
name  Roses   Roses 
section  Floral   Floral 
image  img1.jpg  img2.jpg 
thumb  img1-thm.jpg img2-thm.jpg 

Répondre

0

Je ne suis pas familier avec VB.Net, mais en C# vous pouvez écrire quelque chose comme ceci:

 XDocument doc = XDocument.Load("D:\\file.xml"); 
     var lstProducts = from XElement elem in doc.Element("ProductGroup").Elements("Product") 
          where int.Parse(elem.Element("price").Value) < 54 
          select new 
          { 
           name = elem.Element("name").Value, 
           section = elem.Element("section").Value, 
           image = elem.Element("PopupImages").Element("PopupImage").Value, 
           thumb = elem.Element("ImageThumbs").Element("thumb").Value 
          }; 

Espérons que cela aide.

EDIT: nouvelle requête qui doit gérer la fusion PopupImages et ImageThumbs:

 var lstProducts = from XElement elem in doc.Element("ProductGroup").Elements("Product") 
          where int.Parse(elem.Element("price").Value) < 54 

          let images = elem.Element("PopupImages").Elements("PopupImage") 
          let thumbs = elem.Element("ImageThumbs").Elements("thumb") 

          from img in images.Select(
          (im, idx) => new KeyValuePair<string, string>(im.Value, thumbs.ElementAt(idx).Value) 
         ) 

          select new 
          { 
           name = elem.Element("name").Value, 
           section = elem.Element("section").Value, 
           image = img.Key, 
           thumb = img.Value 
          }; 

Toujours en C#, mais je pense que l'idée est claire.

+0

vérifier la mise à jour – deostroll

+0

@deostroll vérifier la mise à jour :) – Ladislav

1

Essayez cette approche:

Dim query = From product In doc.Elements("Product") 
      Where Integer.Parse(product.Element("price").Value) < 54 
      Select New With 
      { 
       .Name = product.Element("name").Value, 
       .Section = product.Element("section").Value, 
       .Images = product.Descendants("PopupImage").Select(Function(i) i.Value), 
       .Thumbs = product.Descendants("thumb").Select(Function(t) t.Value) 
      } 

For Each item in query 
    Console.WriteLine(item.Name) 
    Console.WriteLine(item.Section) 
    Console.WriteLine("Images:") 
    For Each image in item.Images 
     Console.WriteLine(" " + image) 
    Next 
    Console.WriteLine("Thumbs:") 
    For Each thumb in item.Thumbs 
     Console.WriteLine(" " + thumb) 
    Next 
Next 

Si vous avez vraiment besoin d'une liste il suffit d'appeler query.ToList() et stocker le résultat dans une variable ou joindre la requête originale entre parenthèses et ajouter ToList() (je préfère ne pas le faire pour une meilleure lisibilité). De même, les images et les vignettes sont actuellement de type IEnumerable<string>. Par conséquent, si vous avez besoin d'une liste ou d'un tableau, ajoutez l'appel de méthode d'extension approprié.

+0

vérifier la mise à jour. – deostroll