1

我正在使用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;           
}
4

4 回答 4

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"));

...或沿着这些思路

于 2013-03-30T16:07:08.403 回答
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;        
于 2013-03-30T16:22:32.893 回答
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>.

于 2013-03-30T15:48:27.610 回答
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();
于 2013-03-30T16:24:04.640 回答