2011-12-08 119 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级别有关的淡化示例。 –