2013-03-15 6 views
0

У меня есть следующий XMLИзвлечение элементов из XML с помощью LINQ

<Group> 
    <Id>2</Id> 
    <GroupName>Fizzy Drinks</GroupName> 
    <DateCreated>0001-01-01T00:00:00</DateCreated> 
    <DateModified>0001-01-01T00:00:00</DateModified> 
    <Person> 
     <PersonId>78</PersonId> 
     <PersonName>Francesca</PersonName> 
     <PersonSurname>Andrews</PersonSurname> 
     <PersonAge>59</PersonAge> 
    </Person> 
    <Products> 
     <ProductId>2</ProductId> 
     <ProductName>Oranges</ProductName> 
     <CategoryId>4</CategoryId> 
     <CategoryName></CategoryName> 
     <SubCategoryId>7</SubCategoryId> 
     <SubCategoryName>Bread</SubCategoryName> 
    </Products> 
    <Products> 
     <ProductId>12</ProductId> 
     <ProductName>Pepsi</ProductName> 
     <CategoryId>4</CategoryId> 
     <CategoryName></CategoryName> 
     <SubCategoryId>8</SubCategoryId> 
     <SubCategoryName>Dairy</SubCategoryName> 
    </Products> 
    <Products> 
     <ProductId>14</ProductId> 
     <ProductName>Multiwheat Bread</ProductName> 
     <CategoryId>4</CategoryId> 
     <CategoryName></CategoryName> 
     <SubCategoryId>7</SubCategoryId> 
     <SubCategoryName>Bread</SubCategoryName> 
    </Products> 
</Group> 

И я хочу, чтобы извлечь следующие внутри объекта группы.

У меня есть следующий код: -

  foreach (XElement xe in xdoc.Descendants("Group")) 
     { 
      int id = Convert.ToInt32(xe.Element("Id").Value); 

      var group = from g in xdoc.Descendants("Group") 
         where (int)g.Element("Id") == id // filtering groups here 
         select new Group 
         { 
          Id = (int)g.Element("Id"), 
          GroupName = (string)g.Element("GroupName"), 
          DateCreated = (DateTime)g.Element("DateCreated"), 
          DateModified = (DateTime)g.Element("DateModified"), 
          Person = from d in g.Descendants("Person") 
            select new Person 
             { 
              Id = (int)d.Element("PersonId"), 
              Name = (string)d.Element("PersonName"), 
              Surname = (string)d.Element("PersonSurname"), 
              Age = (int)d.Element("PersonAge"), 
             }, 

          PersonId = (int)g.Element("PersonId"), 
          PersonName = (string)g.Element("PersonName"), 
          PersonSurname = (string)g.Element("PersonSurname"), 
          PersonAge = (int)g.Element("PersonAge"), 
          Products = g.Elements("Products") 
           .Select(p => new Product 
           { 
            Id = (int)p.Element("ProductId"), 
            ProductName = (string)p.Element("ProductName") 
           }).ToList() 
         }; 

      foreach (var g in group) 
      { 
       GroupList.Add(g); 
      } 

     } 

Однако я получаю сообщение об ошибке, так как человек не IEnumerable. Однако, поскольку у меня будет только 1 человек на группу, я не хочу, чтобы это было IEnumerable. Есть ли способ обойти это?

Спасибо за вашу помощь и время

ответ

0

Это звучит, как вы могли сделать:

Person = (from d in g.Elements("Person") 
      select new Person 
      { 
       Id = (int)d.Element("PersonId"), 
       Name = (string)d.Element("PersonName"), 
       Surname = (string)d.Element("PersonSurname"), 
       Age = (int)d.Element("PersonAge"), 
      }).First() 

, но лучше было бы написать:

Person = Person.FromXElement(g.Element("Person")) 

где FromXElement статический метод в Person, как это:

public static Person FromXElement(XElement element) 
{ 
    return new Person 
    { 
     Id = (int) element.Element("PersonId"), 
     Name = (string) element.Element("PersonName"), 
     Surname = (string) element.Element("PersonSurname"), 
     Age = (int) element.Element("PersonAge") 
    }; 
} 

Таким образом, ваш запрос будет намного яснее.

+0

Thanks Jon Мне нравится это решение! – Johann

0

Это лучше сделать объявить новую переменную диапазона, которая будет содержать <Person> элемент и использовать его позже

var group = from g in xdoc.Descendants("Group") 
      let person = g.Element("Person") // here 
      where (int)g.Element("Id") == id 
      select new Group { 
       ... 
      } 

и использовать его:

Person = new Person { 
      Id = (int)person.Element("PersonId"), 
      Name = (string)person.Element("PersonName"), 
      Surname = (string)person.Element("PersonSurname"), 
      Age = (int)person.Element("PersonAge") 
      }, 

Вы можете также добавьте null проверьте, возможно ли, что в вашем XML-элементе нет элемента person:

Person = (person == null) ? null : 
      new Person { 
       Id = (int)person.Element("PersonId"), 
       Name = (string)person.Element("PersonName"), 
       Surname = (string)person.Element("PersonSurname"), 
       Age = (int)person.Element("PersonAge") 
      }, 
Смежные вопросы