HTML 민첩성 팩 - 컨텐츠를 제거하지 않고 원하지 않는 태그를 제거 하시겠습니까?

c# html-agility-pack

문제

몇 가지 관련 질문을 여기에서 보았지만, 나는 그들이 직면하고있는 것과 같은 문제에 관해 정확히 이야기하지는 않습니다.

HTML Agility Pack 을 사용하여 태그에서 내용을 잃지 않고 HTML에서 원치 않는 태그를 제거하고 싶습니다.

예를 들어, 제 시나리오에서는 " b ", " i "및 " u "태그를 보존하고 싶습니다.

그리고 다음과 같은 입력에 대해서 :

<p>my paragraph <div>and my <b>div</b></div> are <i>italic</i> and <b>bold</b></p>

결과 HTML은 다음과 같아야합니다.

my paragraph and my <b>div</b> are <i>italic</i> and <b>bold</b>

HtmlNodeRemove 메서드를 사용하여 시도했지만 내용도 삭제됩니다. 어떤 제안?

수락 된 답변

Oded의 제안에 기반한 알고리즘을 작성했습니다. 여기있어. 매력처럼 작동합니다.

strong , em , u 및 원시 텍스트 노드를 제외한 모든 태그를 제거합니다.

internal static string RemoveUnwantedTags(string data)
{
    if(string.IsNullOrEmpty(data)) return string.Empty;

    var document = new HtmlDocument();
    document.LoadHtml(data);

    var acceptableTags = new String[] { "strong", "em", "u"};

    var nodes = new Queue<HtmlNode>(document.DocumentNode.SelectNodes("./*|./text()"));
    while(nodes.Count > 0)
    {
        var node = nodes.Dequeue();
        var parentNode = node.ParentNode;

        if(!acceptableTags.Contains(node.Name) && node.Name != "#text")
        {
            var childNodes = node.SelectNodes("./*|./text()");

            if (childNodes != null)
            {
                foreach (var child in childNodes)
                {
                    nodes.Enqueue(child);
                    parentNode.InsertBefore(child, node);
                }
            }

            parentNode.RemoveChild(node);

        }
    }

    return document.DocumentNode.InnerHtml;
}

인기 답변

html 문자열에서 원치 않는 html 태그 목록을 반복적으로 제거하는 방법

나는 @mathias 응답을 가져 왔고 Extension 메서드를 개선하여 List<string> (예 : {"a","p","hr"} )로 제외 할 태그 목록을 제공 할 수있었습니다. 또한 논리가 고정되어 재귀 적으로 올바르게 작동합니다.

public static string RemoveUnwantedHtmlTags(this string html, List<string> unwantedTags)
    {
        if (String.IsNullOrEmpty(html))
        {
            return html;
        }

        var document = new HtmlDocument();
        document.LoadHtml(html);

        HtmlNodeCollection tryGetNodes = document.DocumentNode.SelectNodes("./*|./text()");

        if (tryGetNodes == null || !tryGetNodes.Any())
        {
            return html;
        }

        var nodes = new Queue<HtmlNode>(tryGetNodes);

        while (nodes.Count > 0)
        {
            var node = nodes.Dequeue();
            var parentNode = node.ParentNode;

            var childNodes = node.SelectNodes("./*|./text()");

            if (childNodes != null)
            {
                foreach (var child in childNodes)
                {
                    nodes.Enqueue(child);                       
                }
            }

            if (unwantedTags.Any(tag => tag == node.Name))
            {               
                if (childNodes != null)
                {
                    foreach (var child in childNodes)
                    {
                        parentNode.InsertBefore(child, node);
                    }
                }

                parentNode.RemoveChild(node);

            }
        }

        return document.DocumentNode.InnerHtml;
    }



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.