开发者

Find values from Xml who have same Element Name

I have following xml which same child element (Filed) and I want to get value from each Child element.

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>

Code

  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.Ele开发者_运维知识库ment("books").Attribute("genre").Value
                         ,Price = "?"
                         ,PublishDate="?"
                         ,Title="?"
                   };

Book Class

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


This will give you what you're looking for. Of course, if there is a possibility of any of these attributes not always being present, you'd want to add some null value checks to make sure each attribute exists before calling it's Value property.

Once you have the <books> element inside your query, you can do sub queries to select the specific <Field> elements that you need.

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

One note on the code you posted in the question. The method xdoc.Descendants("root") doesn't really do anything. from book in xdoc would do the same thing. I used Descendants("books") in my answer, which is what I think you meant to do anyway.


I agree with Dennis xdoc.Descendants("root") doesn't really do anything.

I modify code so it will check attrbiute exists or not also how you can use lambda expression.

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


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

I think this is how I would do it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜