Найти значения из XML, которые имеют одинаковое имя элемента - PullRequest
1 голос
/ 22 декабря 2009

У меня есть следующий XML, какой дочерний элемент (Filed) и я хочу получить значение от каждого дочернего элемента.

Sameple XML

 <root xmlns="">
    <books cat="F1" ISBN="01F187597" genre="Programming">
      <Field name="Title" val="XML" /> 
      <Field name="Publish Date" val="20010424" /> 
      <Field name="Price" val="43.00" /> 
    </books>
 </root>

Код

  XDocument xdoc = XDocument.Load("c:\\test6.xml");

  var booksData = from book in xdoc.Descendants("root")
                  //I guess create this and do something with it
                  // let fieldElements = book.Descendants("Field")
                  select new Book
                  {
                         cat = book.Element("books").Attribute("cat").Value
                         ,ISBN = book.Element("books").Attribute("ISBN").Value
                         ,genre = book.Element("books").Attribute("genre").Value
                         ,Price = "?"
                         ,PublishDate="?"
                         ,Title="?"
                   };

Книжный класс

 public class Book
  {
    public string cat {get;set;}
    public string ISBN {get;set;}
    public string genre {get;set;}
    public string Title {get;set;}
    public string PublishDate {get;set;}
    public string Price { get; set; }
  }

Ответы [ 3 ]

0 голосов
/ 22 декабря 2009

Я согласен с Деннисом xdoc. Descendants ("root") ничего не делает.

Я изменяю код, чтобы он проверял, существует ли атрибут или нет, а также как вы можете использовать лямбда-выражения.

  var booksData = from book in xdoc.Descendants("books")
                            select new Book
                            {
                                cat = book.Attribute("cat").Value,
                                ISBN = book.Attribute("ISBN").Value,
                                genre = book.Attribute("genre").Value,

                                //Dennis Code 

                               Price = (from childField in book.Elements()
                                         where childField.Attribute("name").Value == "Price"
                                         select childField.Attribute("val").Value).SingleOrDefault(),

                                //same as Dennis code but using lambda expression

                                PublishDate = book.Elements("Field").Where(p => p.Attribute("name").Value == "Publish Date")
                                              .Select(p => p.Attribute("val").Value).SingleOrDefault(),

                                 // Check if element exists or not 
                                 //if not exists it will insert empty string

                               Title = book.Elements("Field").Any( p => p.Attribute("name").Value == "Title")
                                        ? book.Elements("Field").Where(p=> p.Attribute("name").Value == "Title")
                                          .Select(p => p.Attribute("val")== null
                                                  ? string.Empty
                                                  : p.Attribute("val").Value
                                                  ).Single()
                                        : string.Empty                                };
0 голосов
/ 23 декабря 2009
string xml = @"<root xmlns=''>    <books cat='F1' ISBN='01F187597' genre='Programming'>      <Field name='Title' val='XML' />       <Field name='Publish Date' val='20010424' />       <Field name='Price' val='43.00' />     </books> </root>";



            XDocument xdoc = XDocument.Parse(xml);

            var booksData = from book in xdoc.Descendants("root")
                            //I guess create this and do something with it
                            // let fieldElements = book.Descendants("Field")
                            select new Book
                            {
                                cat = book.Element("books").Attribute("cat").Value
                                   , ISBN = book.Element("books").Attribute("ISBN").Value
                                   , genre = book.Element("books").Attribute("genre").Value
                                   , Price = book.Elements("books").Elements("Field").Single(b => b.Attribute("name").Value == "Price").Attribute("val").Value
                                   , PublishDate = book.Elements("books").Elements("Field").Single(b => b.Attribute("name").Value == "Publish Date").Attribute("val").Value
                                   , Title = book.Elements("books").Elements("Field").Single(b => b.Attribute("name").Value == "Title").Attribute("val").Value
                            };

        }


        public class Book
        {
            public string cat { get; set; }
            public string ISBN { get; set; }
            public string genre { get; set; }
            public string Title { get; set; }
            public string PublishDate { get; set; }
            public string Price { get; set; }
        }

Я думаю, что так бы и поступил.

0 голосов
/ 22 декабря 2009

Это даст вам то, что вы ищете. Конечно, если есть вероятность того, что какой-либо из этих атрибутов присутствует не всегда, вам нужно добавить несколько проверок нулевого значения, чтобы убедиться, что каждый атрибут существует до вызова его свойства Value.

Если в вашем запросе есть элемент <books>, вы можете выполнить подзапросы, чтобы выбрать нужные вам элементы <Field>.

var booksData = from book in xdoc.Descendants("books")
                select new Book
                           {
                               cat = book.Attribute("cat").Value,
                               ISBN = book.Attribute("ISBN").Value,
                               genre = book.Attribute("genre").Value,
                               Price = (from childField in book.Elements()
                                        where childField.Attribute("name").Value == "Price"
                                        select childField.Attribute("val").Value).SingleOrDefault(),
                               PublishDate = (from childField in book.Elements()
                                              where childField.Attribute("name").Value == "Publish Date"
                                              select childField.Attribute("val").Value).SingleOrDefault(),
                               Title = (from childField in book.Elements()
                                        where childField.Attribute("name").Value == "Title"
                                        select childField.Attribute("val").Value).SingleOrDefault()
                           };

Одна заметка о коде, который вы разместили в вопросе. Метод xdoc.Descendants("root") на самом деле ничего не делает. from book in xdoc сделал бы то же самое. Я использовал Descendants("books") в своем ответе, что, по-моему, вы все равно хотели сделать.

...