2011-06-08 79 views
1

我有一個xml文件,如下所示:的LINQ to XML:創建複雜的匿名類型

<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> 

在生產ProductGroup節點可能包含許多產品的節點。爲此,我有種想建立一個具有以下屬性的匿名對象的列表:

name 
section 
image 
thumb 

我能夠得到使用的XDocument產品元素的列表。

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

從這裏我該怎麼辦?

更新:

讓我更好地解釋這一點。我不確定我是否正確傳達了這一點。

以上面的xml示例本身。我寫的上面的代碼返回具有指定「where」條件的所有產品元素。現在每個返回的XmlElement(產品)我必須創建n個匿名對象。數字n取決於PopupImages和ImageThumbs節點有多少個孩子。然而,就我而言,這個數字將是一樣的。因此回來上面的例子中,我得到了兩個匿名對象:

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

回答

0

我不熟悉VB.Net,但在C#中,你會寫是這樣的:

 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 
          }; 

希望這有助於。

編輯:應處理合並PopupImages和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 
          }; 

仍然在C#中,但我認爲這個想法是清楚的。

+0

檢查更新 – deostroll 2011-06-11 10:07:00

+0

@deostroll檢查更新:) – Ladislav 2011-06-13 21:19:43

1

試試這個辦法:

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 

如果你真的需要一個名單只是調用query.ToList()並將結果存儲在一個變量或括號括起來的原始查詢和追加ToList()(我不喜歡的可讀性做到這一點)。同樣,圖像和縮略圖目前的類型爲IEnumerable<string>,所以如果您需要列表或數組,請添加適當的擴展方法調用。

+0

檢查更新。 – deostroll 2011-06-11 10:06:47