2011-12-08 147 views
1

這是我解析的XML:空對象引用

<FEED> 
<FEED_HEADER> 
    <FEED_NAME>foo</FEED_NAME> 
    <FEED_CODE>foobar123</FEED_CODE> 
</FEED_HEADER> 
<FEED_CONTENT> 
    <DOC> 
     <PUB_DATE>2011-12-01</PUB_DATE> 
     <TITLE>Monkey Bombs</TITLE> 
    </DOC> 
    <DOC> 
     <PUB_DATE>2011-12-10</PUB_DATE> 
     <TITLE>A Silly Hat</TITLE> 
    </DOC> 
    <DOC> 
     <PUB_DATE>2011-12-25</PUB_DATE> 
     <TITLE>Wind Blows Up My Skirt</TITLE> 
    </DOC> 
</FEED_CONTENT> 
</FEED> 

而且我用我已經寫建立一個基於對象的列表,這個LINQ代碼解析它商務部元素和它的後續元素:

public List<Review> GetReviews(string filePath, FileInfo file, DirectoryInfo directory, XElement xmlDoc) 
    { 
     IEnumerable<BookReview> reviews = null; 
     try 
     { 
      reviews = from item in xmlDoc.Descendants("DOC") 
         select new BookReview() 
         { 
          PubDate = item.Element("PUB_DATE").Value, 
          Title = item.Element("TITLE").Value, 
         }; 
     } 
     catch (Exception ex) 
     { 
      logger.Info(string.Format("Error while parsing file {0}\n", file.Name) + " " + ex.Message.ToString()); 
     } 

     return reviews.Cast<Review>().ToList(); 
    } 

在過去,這個代碼將工作在DOC元素只是根元素之下,現在的DOC元件進一步嵌套到FEED_CONTENT元素,我得到一個空引用異常。我認爲LINQ可以直接訪問我想要的而不知道它在層次結構中的位置。 那麼現在我需要寫什麼來訪問DOC元素?

+1

這應該工作。您粘貼的XML雖然不完整或無效。 – BrokenGlass

回答

3

根據當前的XML示例,您當前的查詢應該可以正常工作。我懷疑你的真正的XML文檔丟失PUB_DATETITLE元素,這將導致NullReferenceException拋出。

在這種情況下,就可以把元素爲字符串,而不是試圖訪問Value屬性。如果元素不存在,它將返回一個空結果,您將需要通過稍後在過程中編寫其他邏輯來正確處理該結果。

PubDate = (string)item.Element("PUB_DATE"), 
Title = (string)item.Element("TITLE") 
+0

所以你說這兩個元素或缺失的元素可能缺少一個值?這可能就是這種情況,因爲真正的XML非常大,有數百個DOC元素。 –

+0

@fullNelson缺少一個元素,而不是一個空元素。一個空元素(或缺失值)將被視爲'String.Empty'。 –

+1

+1不使用「值」。類型轉換更安全和更好。它處理大多數類型,比如'int','bool'等。這是Linq-Xml的一個主要特性。 – Mig

0

你從你的查詢點的方式進入FEED_CONTENT英寸這就像

reviews = from item in xmlDoc.Element("FEED_CONTENT").Descendants("DOC") 
    select new BookReview() 
    { 
     PubDate = item.Element("PUB_DATE").Value, 
     Title = item.Element("TITLE").Value 
    } 
}; 
+0

就像您在發佈這個問題之前所建議的那樣,我「走了」我的路,而且它似乎根本不起作用。我不想知道是否有關於訪問XML其他部分的其他內容。不幸的是,XML太複雜,無法完整地發佈。 –

2

我跑你的代碼 - 我遇到的一個問題是你的元素需要關閉。在我以這種方式修改XML之後,我可以很好地處理DOC元素。下面是我跑的代碼:

 public class Review { } 
     public class BookReview : Review 
     { 
      public string PubDate; 
      public string Title; 

     } 
     public static void Main() 
     { 
      string xml = @" 
<FEED> 
<FEED_HEADER> 
    <FEED_NAME>foo</FEED_NAME> 
    <FEED_CODE>foobar123</FEED_CODE> 
</FEED_HEADER> 
<FEED_CONTENT> 
    <DOC> 
     <PUB_DATE>2011-12-01</PUB_DATE> 
     <TITLE>Monkey Bombs</TITLE> 
    </DOC> 
    <DOC> 
     <PUB_DATE>2011-12-10</PUB_DATE> 
     <TITLE>A Silly Hat</TITLE> 
    </DOC> 
    <DOC> 
     <PUB_DATE>2011-12-25</PUB_DATE> 
     <TITLE>Wind Blows Up My Skirt</TITLE> 
    </DOC> 
</FEED_CONTENT> 
</FEED>"; // NOTE: I closed the <FEED> element! 
      var xmlDoc = XDocument.Parse(xml); 
      IEnumerable<BookReview> reviews = null; 
      try 
      { 
       reviews = from item in xmlDoc.Descendants("DOC") 
          select new BookReview() 
          { 
           PubDate = item.Element("PUB_DATE").Value, 
           Title = item.Element("TITLE").Value, 
          }; 
      } 
      catch (Exception ex) 
      { 
       //... 
      } 

      foreach (var review in reviews) 
      { 
       Console.WriteLine("{0}, {1}", review.PubDate, review.Title); 
      } 
      var reviews2 = reviews.Cast<Review>().ToList(); 

      Console.ReadLine(); 
     } 

和輸出:

2011-12-01, Monkey Bombs 
2011-12-10, A Silly Hat 
2011-12-25, Wind Blows Up My Skirt 
+0

感謝JohnD,使用這個簡化的XML,它可以正確運行,必須有其他關於xml的其他信息,我不能正確地在這裏表示,以便任何人都能清楚地瞭解可能存在的錯誤。再次,我不得不使用一個與我正在使用的XML級別有關的淡化示例。 –