HTML Agility Pack으로 부적절한 HTML을 수정하는 방법은 무엇입니까?

.net c# html html-agility-pack parsing

문제

중복 태그가있는이 잘못된 HTML이 있습니다.

<p>word1<b>word2</p>
<p>word3</b>word4</p>

중첩도 중첩 될 수 있습니다.

HTML Agility Pack (HAP)을 사용하여 잘 구성된 HTML로 변환하려면 어떻게해야합니까?

이 출력 찾고 있어요 :

<p>word1<b>word2</p>
<p>word3</b>word4</p>

내가 해봤 HtmlNode.ElementsFlags["b"] = HtmlElementFlag.Closed | HtmlElementFlag.CanOverlap ,하지만 예상대로 작동하지 않습니다.

수락 된 답변

실제로 예상대로 작동하지만 예상대로 작동하지 않을 수 있습니다 . 어쨌든 다음은 라이브러리를 사용하여 HTML을 수정하는 방법을 보여주는 샘플 코드입니다 (콘솔 응용 프로그램).

라이브러리에는 ParseErrors 컬렉션이있어 마크 업 구문 분석 중에 어떤 오류가 감지되었는지 확인할 수 있습니다.

여기에는 실제로 두 가지 유형의 문제가 있습니다.

1) 닫히지 않은 요소들 . 이 라이브러리는 기본적으로 라이브러리에 의해 고정되어 있지만이 경우 P 요소에서이를 방지하는 옵션이 있습니다.

2) 미개봉 요소 . 이 방법은 더 복잡합니다. 수정 방법에 따라 달라지기 때문에 태그를 어디에 열어 놓을까요? 다음 샘플에서는 가장 가까운 이전 텍스트 형제 노드를 사용하여 요소를 엽니 다.

static void Main(string[] args)
{
    // clear the flags on P so unclosed elements in P will be auto closed.
    HtmlNode.ElementsFlags.Remove("p");

    // load the document
    HtmlDocument doc = new HtmlDocument();
    doc.Load("yourTestFile.htm");

    // build a list of nodes ordered by stream position
    NodePositions pos = new NodePositions(doc);

    // browse all tags detected as not opened
    foreach (HtmlParseError error in doc.ParseErrors.Where(e => e.Code == HtmlParseErrorCode.TagNotOpened))
    {
        // find the text node just before this error
        HtmlTextNode last = pos.Nodes.OfType<HtmlTextNode>().LastOrDefault(n => n.StreamPosition < error.StreamPosition);
        if (last != null)
        {
            // fix the text; reintroduce the broken tag
            last.Text = error.SourceText.Replace("/", "") + last.Text + error.SourceText;
        }
    }

    doc.Save(Console.Out);
}

public class NodePositions
{
    public NodePositions(HtmlDocument doc)
    {
        AddNode(doc.DocumentNode);
        Nodes.Sort(new NodePositionComparer());
    }

    private void AddNode(HtmlNode node)
    {
        Nodes.Add(node);
        foreach (HtmlNode child in node.ChildNodes)
        {
            AddNode(child);
        }
    }

    private class NodePositionComparer : IComparer<HtmlNode>
    {
        public int Compare(HtmlNode x, HtmlNode y)
        {
            return x.StreamPosition.CompareTo(y.StreamPosition);
        }
    }

    public List<HtmlNode> Nodes = new List<HtmlNode>();
}



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