2009-12-21 94 views
1

我有以下xml相同的子元素(Filed),我想從每個Child元素獲取值。從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; } 
    } 

回答

0

我與丹尼斯xdoc.Descendants(「根」)同意並沒有真正做任何事情。

我修改代碼,以便它會檢查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        }; 
+0

任何人有更好的辦法了相同的代碼,那麼請張貼 – NETQuestion 2009-12-23 00:15:18

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"),這正是我認爲你無論如何應該做的。

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

我覺得這是我會怎麼做。

+0

你的代碼將無法在以下情況下 工作,如果屬性val爲例如失蹤 <字段名稱= 「標題」/> OR Title元素缺少 <根的xmlns = 「」> <書籍貓= 「F1」 ISBN = 「01F187597」 流派= 「幻想」> <字段名稱=」發佈日期「val =」20010424「/> <字段名稱=」價格「val =」43「/> – NETQuestion 2009-12-23 00:56:13

+0

您提出一個好的觀點。謝謝 – 2009-12-23 01:22:11

相關問題