LINQ to XML:创建复杂的匿名类型

发布于 2024-11-14 16:49:32 字数 1359 浏览 4 评论 0原文

我有一个 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 获取 Product 元素的列表。

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

I've an xml file as follows:

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

In production the ProductGroup node might contain many Product nodes. For this I kind of want to build a list of an anonymous object that has the following properties:

name 
section
image
thumb

I am able to get a list of Product elements using XDocument.

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

From here what do I do?

Update:

Let me explain this better. I am not sure if I have communicated this properly.

Taking the above xml example itself. The above code I've written returns all product elements with the specified "where" condition. Now for each XmlElement returned (product) I've to create n-number of anonymous objects. The number n depends on how many children are there for the PopupImages and ImageThumbs nodes. In my case however, the number will be the same. Hence coming back to the above example, I'd get two anonymous objects:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜`诱少女 2024-11-21 16:49:32

尝试这种方法:

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,因此如果您需要列表或数组,请添加适当的扩展方法调用。

Try this approach:

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

If you really need a list just call query.ToList() and store the result in a variable or enclose the original query in parentheses and append ToList() (I prefer not to do this for readability). Similarly, the images and thumbnails are currently of type IEnumerable<string>, so if you need a list or array add the appropriate extension method call.

紫南 2024-11-21 16:49:32

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

I'm not familiar with VB.Net, but in C# you'd write something like this:

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

Hope this helps.

EDIT: new query that should handle merging PopupImages and 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
                          };

Still in C#, but I think the idea is clear.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文