这是我正在解析的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代码解析它,以基于DOC元素及其后续元素构建对象列表:
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元素?
答案 0 :(得分:3)
根据您当前的XML示例,您当前的查询应该可以正常工作。我怀疑您的真实XML文档缺少PUB_DATE
或TITLE
元素,这会导致NullReferenceException
被抛出。
在这种情况下,您可以将元素转换为字符串,而不是尝试访问Value
属性。如果该元素不存在,它将返回一个null结果,您需要通过稍后在过程中编写其他逻辑来正确处理。
PubDate = (string)item.Element("PUB_DATE"),
Title = (string)item.Element("TITLE")
答案 1 :(得分: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
答案 2 :(得分: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
}
};