如何从像编号目录这样的 html 字符串中仅提取标题(即 h2、h3、h4)?

How to extract only the headings (i.e h2,h3,h4), from a html string like a numbered TOC?

提问人:Zacke 提问时间:2/14/2019 更新时间:2/14/2019 访问量:2276

问:

我想从 xhtml 字符串中提取标题标签(即 h1、h2、h3 等)中的所有内容,然后在侧菜单中使用。

xhtml 字符串将具有编号的标题,因此 h2 将类似于“1.1 Heading”,而在其下是带有“1.1.1 Heading”和 1.1.2 的 h3,依此类推。

<div class="main-body">
    <h2>1.1 Heading</h2>
    <h3>1.1.1 Subheading</h3>
    <p>Lorem ipsum</p>
    <h3>1.1.2 Another Subheading</h3>
    <p>Lorem ipsum</p>

    <h2>2.1 Heading</h2>
    <h3>2.1.1 Subheading</h3>
    <p>Lorem ipsum</p>
    <h4>2.1.1.1 SubSubHeading</h4>
</div>

上面是 html 外观的示例,因此我想将父 (h2) 与它的子项(h3、h4)分组,当在 DOM 中找到新的 h2 时,我想创建一个包含其“子项”的新组。

C# HTML XHTML

评论

0赞 er-sho 2/14/2019
我想你忘了查看下面的答案,如果你遇到任何问题,请告诉我:)
0赞 Zacke 2/14/2019
@er-sho:不,我:)看到的不过,我被困在一个会议中,现在经过测试,它工作正常。不错的详细答案!剩下的就是弄清楚标题的层次结构,这样我就可以在菜单中相应地显示它们。:D
0赞 er-sho 2/14/2019
如果我的答案对您有所帮助,请在左侧标记勾号,使其变为绿色。因此,它使我的努力值得:)

答:

3赞 er-sho 2/14/2019 #1

有两种方法可以检索要标记的所有文本<h1><h6>

所以你的输入html是:

string input = @"<div class='main - body'>
                     <h2> 1.1 Heading </h2>     
                     <h3> 1.1.1 Subheading </h3>        
                     <p> Lorem ipsum </ p >           
                     <h3> 1.1.2 Another Subheading</h3>              
                     <p> Lorem ipsum </p>     
                     <h2> 2.1 Heading </h2>
                     <h3> 2.1.1 Subheading </h3>
                     <p> Lorem ipsum </p>
                     <h4> 2.1.1.1 SubSubHeading </h4>
                 </div> ";

1) 通过使用正则表达式:

使用此正则表达式将标题标记内的所有文本从 获取到<h1><h6>

<h[1-6][^>]*?>(?<TagText>.*?)</h[1-6]>

用法:

string pattern = @"<h[1-6][^>]*?>(?<TagText>.*?)</h[1-6]>";

MatchCollection matches = Regex.Matches(input, pattern);

var heading_matches = matches.Cast<Match>().Select(x => x.Groups["TagText"].Value);

忽略然后使用h1

string pattern = @"<h[2-6][^>]*?>(?<TagText>.*?)</h[2-6]>";

2) 通过使用 HtmlAgilityPack:

使用 HtmlAgilityPack 包将 .<h1><h6>

需要从 NuGet 包管理器控制台安装此包。

Install-Package HtmlAgilityPack -Version 1.8.14

用法:

var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(input);

string xpathQuery = "//*[starts-with(name(),'h') and string-length(name()) = 2 and number(substring(name(), 2)) <= 6]";

var texts = htmlDocument.
                DocumentNode
                .SelectNodes(xpathQuery)
                .Select(x => x.InnerText)
                .ToList();

忽略然后使用h1

string xpathQuery = "//*[starts-with(name(),'h') and string-length(name()) = 2 and number(substring(name(), 2)) > 1 and number(substring(name(), 2)) <= 6]";

输出:(来自调试器)

enter image description here