从具有相同元素名称的Xml中查找值

时间:2009-12-21 22:57:04

标签: c#-3.0 linq-to-xml

我有跟随xml的同一个子元素(已归档),我想从每个子元素中获取值。

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 :(得分:0)

这将为您提供所需的信息。当然,如果有可能不存在任何这些属性,那么您需要添加一些空值检查,以确保在调用它的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"),这是我认为你打算做的事情。

答案 1 :(得分:0)

我同意Dennis xdoc.Descendants(“root”)并没有真正做任何事情。

我修改了代码,因此它会检查是否存在attrbiute,以及如何使用lambda表达式。

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

答案 2 :(得分:0)

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

我认为我会这样做。