【问题标题】:Getting content between two HTML tags using Html Agility Pack使用 Html Agility Pack 在两个 HTML 标记之间获取内容
【发布时间】:2012-05-29 22:13:21
【问题描述】:

我们在 Word 中创建了一个绝对庞大的帮助文档,它被用来生成一个更大且笨拙的 HTM 文档。使用 C# 和这个库,我只想在我的应用程序的任何位置抓取并显示这个文件的一部分。部分是这样划分的:

<!--logical section starts here -->
<div>
<h1><span style='mso-spacerun:yes'></span><a name="_Toc325456104">Section A</a></h1>
</div>
 <div> Lots of unnecessary markup for simple formatting... </div>
 .....
<!--logical section ends here -->

<div>
<h1><span style='mso-spacerun:yes'></span><a name="_Toc325456104">Section B</a></h1>
</div>

从逻辑上讲,H1a 标记中有一个部分名称。我想从包含 div 的外部选择所有内容,直到遇到另一个 h1 并排除该 div。

  • 每个部分名称位于h1 下的&lt;a&gt; 标记中,该标记有多个子项(每个大约6 个)
  • 逻辑部分用 cmets 标记
  • 实际文档中不存在这些 cmets

我的尝试:

var startNode = helpDocument.DocumentNode.SelectSingleNode("//h1/a[contains(., '"+sectionName+"')]");
//go up one level from the a node to the h1 element
startNode=startNode.ParentNode;

//get the start index as the index of the div containing the h1 element
int startNodeIndex = startNode.ParentNode.ChildNodes.IndexOf(startNode);

//here I am not sure how to get the endNode location. 
var endNode =?;

int endNodeIndex = endNode.ParentNode.ChildNodes.IndexOf(endNode);

//select everything from the start index to the end index
var nodes = startNode.ParentNode.ChildNodes.Where((n, index) => index >= startNodeIndex && index <= endNodeIndex).Select(n => n);

Sine 我无法找到这方面的文档,我不知道如何从我的起始节点到下一个 h1 元素。任何建议将不胜感激。

【问题讨论】:

    标签: c# .net html-agility-pack


    【解决方案1】:

    我认为这可以做到,尽管它假设 H1 标签只出现在章节标题中。如果不是这种情况,您可以在后代上添加 Where 以检查它找到的任何 H1 节点上的其他过滤器。请注意,这将包括它找到的 div 的所有兄弟姐妹,直到找到具有部分名称的下一个。

    private List<HtmlNode> GetSection(HtmlDocument helpDocument, string SectionName)
    {
        HtmlNode startNode = helpDocument.DocumentNode.Descendants("div").Where(d => d.InnerText.Equals(SectionName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
        if (startNode == null)
            return null; // section not found
    
        List<HtmlNode> section = new List<HtmlNode>();
        HtmlNode sibling = startNode.NextSibling;
        while (sibling != null && sibling.Descendants("h1").Count() <= 0)
        {
            section.Add(sibling);
            sibling = sibling.NextSibling;
        }
    
        return section;
    }
    

    【讨论】:

    • 不错。我不得不稍微更改过滤器,因为我在文档中有多个带有部分名称的 div。我最终使用HtmlNode startNode = helpDocument.DocumentNode.Descendants("h1").Where(d =&gt; d.InnerText.Contains(SectionName)).FirstOrDefault(); 并从那里向上移动到父节点。其余的工作完美。谢谢
    【解决方案2】:

    那么,您真正想要的结果是 h1-Tag 周围的 div 吗? 如果是,那么这应该可以。

    helpDocument.DocumentNode.SelectSingleNode("//h1/a[contains(@name, '"+sectionName+"')]/ancestor::div");
    

    也适用于SelectNodes,具体取决于您的 Html。 像这样:

    helpDocument.DocumentNode.SelectNodes("//h1/a[starts-with(@name,'_Toc')]/ancestor::div");
    

    哦,在测试这个时,我注意到不适合我的是 contains 方法中的点,一旦我将它更改为 name 属性,一切正常。

    【讨论】:

    • 不完全。我想要 h1 标签周围的 div,但我也希望获得所有未来的 div/span 直到下一个 h1 标签的周围 div。不过还是谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多