【问题标题】:LINQ to XML: creating complex anonymous typeLINQ to XML:创建复杂的匿名类型
【发布时间】:2011-06-08 20:48:25
【问题描述】:

我有一个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 节点可能包含许多 Product 节点。为此,我有点想建立一个匿名对象的列表,它具有以下属性:

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

【问题讨论】:

    标签: linq-to-xml anonymous-objects


    【解决方案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&lt;string&gt;,因此如果您需要列表或数组,请添加适当的扩展方法调用。

    【讨论】:

      【解决方案2】:

      我不熟悉 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#,但我认为这个想法很明确。

      【讨论】:

        猜你喜欢
        • 2012-07-19
        • 1970-01-01
        • 1970-01-01
        • 2011-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多