我有一个发送xml feed的客户端,我使用以下代码解析它。这段代码有效。
reviews = from item in xmlDoc.Descendants("node")
select new ForewordReview()
{
PubDate = (string)item.Element("created"),
Isbn = (string)item.Element("isbn"),
Summary = (string)item.Element("review")
};
获取所有“评论”后,我将IEnumerable转换为List并将其返回。最初,我有一个很好的,很容易解析他们的XML的过去看起来像这样:
<reviews>
<node>
<created>01-01-1900</created>
<ISBN>12345657890123</ISBN>
<Review>This is a nice and silly book</Review>
</node>
<node>
<created>01-01-2011</created>
<ISBN>1236245234554</ISBN>
<Review>This is a stupid book</Review>
</node>
<node>
<created>12-06-1942</created>
<ISBN>1234543234577</ISBN>
<Review>This is a old, naughty book</Review>
</node>
</reviews>
但是,他们已经改变了我们无法访问的架构,现在他们的XML在最终的<node>
标签中添加了一个不包含我正在寻找的欺骗元素的结尾,所以,我的解析打破了这最后一个标签,我抛出一个异常。这是一个例子:
<reviews>
<node>
<created>01-01-1900</created>
<ISBN>12345657890123</ISBN>
<Review>This is a nice and silly book</Review>
</node>
<node>
<created>01-01-2011</created>
<ISBN>1236245234554</ISBN>
<Review>This is a stupid book</Review>
</node>
<node>
<created>12-06-1942</created>
<ISBN>1234543234577</ISBN>
<Review>This is a old, naughty book</Review>
</node>
<node>
<count>4656</count>
</node>
</reviews>
我需要知道是否有办法忽略这个最终标记(它总是在文档的末尾),即使它与我正在寻找的所有其他“节点”标记具有相同的名称。我确实尝试了解这段代码,但如果发现此错误,它不会返回好的评论列表。
谢谢你们。
答案 0 :(得分:4)
如果它始终是最后一个节点,
var nodes = xmlDoc.Descendants("node");
reviews = nodes.Take(nodes.Count() - 1).Select(...);
答案 1 :(得分:2)
这样的事情可以解决问题:
var reviews = from item in xmlDoc.Descendants("node").Where(x => x.Element("created") != null)
select new
{
PubDate = (string)item.Element("created"),
Isbn = (string)item.Element("isbn"),
Summary = (string)item.Element("review")
};
如果愿意,您可以对其他元素进行额外的空检查。
答案 2 :(得分:1)
添加空检查
PubDate = (string)(item.Element("created") ?? ""),
Isbn = (string)(item.Element("isbn") ?? ""),
Summary = (string)(item.Element("review") ?? "")
始终将null检查添加到您执行的所有操作中。只是好习惯。在这种情况下,它将消除此错误,但可能会在您假设这些字符串不为空的程序中稍后出现错误,因此请确保稍后再进行空检查。
答案 3 :(得分:1)
您可以计算节点数,然后使用Where的重载,它也会传递一个索引号:(http://msdn.microsoft.com/en-us/library/bb549418.aspx)
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, int, bool> predicate)
所以,像这样:
var count = xmlDoc.Descendants("node").Count();
xmlDoc.Descendants("node").Where((node,index) => index < count-1).Select(..)
答案 4 :(得分:0)
你可以在那里抛出“where”子句。
reviews = from item in xmlDoc.Descendants("node") where item.Descendants().Any(n => n.Name == "Review")
select new ForewordReview()
{
PubDate = (string)item.Element("created"),
Isbn = (string)item.Element("isbn"),
Summary = (string)item.Element("review")
};
此示例只是检查名为“Review”的子节点,因此最好检查所有必需的子节点。