【问题标题】:Using Html Agility Pack to select all paragraphs that start with a certain text value使用 Html Agility Pack 选择所有以某个文本值开头的段落
【发布时间】:2021-03-24 21:59:55
【问题描述】:

我正在学习使用 Html Agility Pack。

我有一系列看起来像这样的段落元素(为了清楚起见,代码拆分):

<p class="rvps2">
    <img alt="New Version Icon" 
         style="vertical-align: middle; padding : 1px; margin : 0px 5px;"
         src="lib/IMG_NewVersion.png">
    <span class="rvts16">Version 21.1.0 - 2021 Edition</span>
    <span class="rvts15"> (22nd March 2021)</span>
</p>

我只对以文本“版本”开头的段落感兴趣。目前我正在这样做:

// Select all Paragraph elements
var nodesParagraph = nodeRevHist.SelectNodes("p");

int iRevisionCount = 0;
foreach (HtmlNode itemParagraph in nodesParagraph)
{
    string text = itemParagraph.InnerText;
    if (text.Length > 7 && text.Substring(0, 7) == "Version")
    {
        iRevisionCount++;

nodesParagraph 是否可以过滤到所有内部文本以“版本”开头的段落?

如果可能的话,这将使我的代码更简洁。附带问题,我也只对这些段落元素中的前 5 个元素感兴趣。

这种过滤可能吗?

【问题讨论】:

  • 您真的需要自己检查长度和子字符串吗? text.StartsWith("Version ") 不会每次都分配一个新的字符串,如果text 太短就会返回 false。
  • @madreflection 太棒了。我更熟悉 C++,并没有注意到列表中的那个方法。谢谢。
  • 还有Contains方法,text.Contains("Version")
  • 如果 rvts16 类对于这些段落是唯一的,那么您应该首先查看是否可以对其进行过滤。
  • @madreflection 我不想依赖类名,因为它们是在我构建帮助文件时由 HelpNDoc 提供的。所以这些类名可能会改变。我已经在文件中隔离了正确的div 元素,并且我的历史内容遵循严格的模式。所以我认为我使用这种方法是安全的。

标签: c# html-agility-pack


【解决方案1】:

您可以获得内部文本以“版本”开头的前 5 个段落,如下所示:

var nodesParagraph = nodeRevHist
    .Elements("p")
    .Where(p => p.InnerText.Trim().StartsWith("Version"))
    .Take(5);

这里的工作演示:https://dotnetfiddle.net/uvwcUN

【讨论】:

  • 谢谢。我说得对吗,即使是空的,也可以保证创建一个变量?还是将其包装在 try / catch 块中仍然明智?
  • 我对此做了一些实验。如果nodeRevHist 中没有p 元素,则SelectNodes 返回null,这使得Where 子句崩溃。但是,如果您切换到使用Elements 方法而不是SelectNodes,那么它可以工作,假设nodeRevHist 本身不为空。所以你肯定需要一个空检查来防止这种情况。如果您不确定输入,try/catch 将是最安全的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 2011-06-12
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
相关资源
最近更新 更多