LINQ to XML: создание сложного анонимного типа - PullRequest
1 голос
/ 09 июня 2011

У меня есть 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

Я могу получить список элементов Product, используя XDocument.

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

Отсюда, что мне делать?

Обновление:

Позвольте мне объяснить это лучше. Я не уверен, правильно ли я сообщил об этом.

Взяв приведенный выше пример xml. Приведенный выше код возвращает все элементы продукта с указанным условием «где». Теперь для каждого возвращаемого 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

Ответы [ 2 ]

1 голос
/ 09 июня 2011

Попробуйте этот подход:

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 голосов
/ 09 июня 2011

Я не знаком с 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 #, но я думаю, что идея ясна.

...