You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HTML Agility Pack移除嵌套strong和em标签的实现问题

Solution: Strip Nested Bold/Italic Tags with HTML Agility Pack

Got it, let's fix that nested emphasis tag problem you're facing. The issue with your current code is that it only handles single-level nesting—we need a recursive approach to strip all inner <b>, <strong>, <i>, and <em> tags while preserving the outermost one, no matter how deep the nesting goes.

Step-by-Step Explanation

The core idea is:

  1. Identify all "outermost" emphasis tags (those not wrapped inside another bold/italic tag).
  2. Recursively traverse each outermost tag's descendants, removing any nested emphasis tags and merging their content into the parent.

Working Code

Here's a complete implementation using HTML Agility Pack:

using HtmlAgilityPack;
using System.Collections.Generic;
using System.Linq;

public static class HtmlCleaner
{
    private static readonly HashSet<string> _emphasisTags = new HashSet<string> 
    { 
        "b", "strong", "i", "em" 
    };

    public static string StripNestedEmphasisTags(string html)
    {
        var doc = new HtmlDocument();
        doc.LoadHtml(html);

        // Find all outermost emphasis tags (not inside another emphasis tag)
        var outerEmphasisNodes = doc.DocumentNode.Descendants()
            .Where(n => _emphasisTags.Contains(n.Name.ToLower()) 
                        && !_emphasisTags.Contains(n.ParentNode.Name.ToLower()))
            .ToList();

        // Process each outermost tag to remove nested emphasis tags
        foreach (var node in outerEmphasisNodes)
        {
            RemoveNestedEmphasisRecursively(node);
        }

        return doc.DocumentNode.OuterHtml;
    }

    private static void RemoveNestedEmphasisRecursively(HtmlNode parentNode)
    {
        // Iterate backwards to avoid index issues when removing nodes
        for (int i = parentNode.ChildNodes.Count - 1; i >= 0; i--)
        {
            var childNode = parentNode.ChildNodes[i];

            if (_emphasisTags.Contains(childNode.Name.ToLower()))
            {
                // Move all child content of the nested tag up to the parent
                parentNode.InsertBefore(childNode.ChildNodes, childNode);
                // Delete the nested emphasis tag itself
                childNode.Remove();
            }
            else
            {
                // Recurse into non-emphasis child nodes to check for deeper nesting
                RemoveNestedEmphasisRecursively(childNode);
            }
        }
    }
}

How to Use It

Call the static method with your input HTML:

string inputHtml = "<b>Hello <strong>world <i>foo</i></strong></b>";
string cleanedHtml = HtmlCleaner.StripNestedEmphasisTags(inputHtml);
// Output: <b>Hello world foo</b>

Test Cases & Results

  • Single-level nesting: <i>Hi <em>there</em></i> → <i>Hi there</i>
  • Multi-level mixed nesting: <b>abc <i>def <strong>ghi</strong></i></b> → <b>abc def ghi</b>
  • Multiple outer tags: <div>Test <b>xxx</b> <i>yyy <b>zzz</b></i> end</div> → <div>Test <b>xxx</b> <i>yyy zzz</i> end</div>

Key Details

  • Backwards iteration: We loop from the last child to the first to avoid index shifting issues when removing nodes.
  • Recursive traversal: Ensures even deeply nested tags (like 3+ levels down) are stripped properly.
  • Outermost tag check: We only process tags that aren't wrapped inside other emphasis tags, so we don't accidentally strip the tag we want to keep.

内容的提问来源于stack exchange,提问作者trfletch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:36:02