我使用HTMLAgilityPack
来解析一些html。我在使用和xpath
查询结合linq查询时得到了我期望的结果集。有没有办法可以将它们组合成一个LINQ查询?
var test = doc.DocumentNode.SelectNodes("//div[@class='product']");
foreach (var item in test)
{
var result = from input in item.Descendants("span")
where input.Attributes["class"].Value == "Bold"
where input.InnerHtml.ToUpper() == "GetItem"
select input;
return result;
}
答案 0 :(得分:2)
如果你想把所有的跨度聚集在一起(如果我认为你想要的是正确的话)......
我首先将它转换为更流畅的符号(我发现SelectMany
更容易掌握这种方式 - 但那只是我)
(免责声明:我是从内存中写这个,复制/粘贴你的代码 - 目前不是VS的 - 你需要检查,如果有任何问题可以写,但我想我得到了它好的或多或少)
var test = doc.DocumentNode.SelectNodes("//div[@class='product']");
foreach(var item in test)
item.Descendants("span").Where(input => input.Attributes["class"].Value == "Bold").Where(input => input.InnerHtml.ToUpper() == "GetItem").Select(input => input);
最后......
var allSpans = doc.DocumentNode.SelectNodes("//div[@class='product']")
.SelectMany(item => item.Descendants("span").Where(input => input.Attributes["class"].Value == "Bold").Where(input => input.InnerHtml.ToUpper() == "GetItem"));
......或沿着这些方向
答案 1 :(得分:2)
只是想告诉你在Linq做SelectMany的另一种方式。这是一种样式选择,SO中的许多人更喜欢.SelectMany扩展方法,因为他们可以看到Monad如何应用于IEnumerable。我更喜欢这种方法,因为它更接近函数式编程模型的作用。
return from product in doc.DocumentNode.SelectNodes("//div[@class='product']")
from input in product.Descendants("span")
where input.Attributes["class"].Value == "Bold"
where input.InnerHtml.ToUpper() == "GetItem"
select input;
答案 2 :(得分:1)
如果您真的想在一个查询中完成所有操作,可以使用以下内容:
var result = doc.DocumentNode.SelectNodes("//div[@class='product']")
.SelectMany(e => e.Descendants("span")
.Where(x => x.Attributes["class"].Value == "Bold" &&
x.InnerHtml.ToUpper() == "GetItem"))
.ToList();
return result;
为了便于阅读,我建议将它分开一点,更像是这样:
var result = new List<SomeType>();
var nodes = doc.DocumentNode.SelectNodes("//div[@class='product']");
nodes.SelectMany(e => e.Descendants("span")
.Where(x => x.Attributes["class"].Value == "Bold" &&
x.InnerHtml.ToUpper() == "GetItem"));
return result.ToList();
SelectMany()
方法会将内部查询的结果展平为单个IEnumerable<T>
。
答案 3 :(得分:1)
return (
from result in
from item in doc.DocumentNode.SelectNodes("//div[@class='product']")
from input in item.Descendants("span")
where input.Attributes["class"].Value == "Bold"
where input.InnerHtml.ToUpper() == "GetItem"
select input
select result
).First();