ist es möglich, das Problem in HtmlAgilityPack zu beheben, wenn es einen nicht geschlossen HTML-Tag ist?

StackOverflow https://stackoverflow.com/questions/1928293

  •  20-09-2019
  •  | 
  •  

Frage

Nun, ich habe folgendes Problem.
die html ich habe ist falsch formatiert, und ich habe Probleme mit der Auswahl Knoten mit HTML Agilität packen, wenn dies der Fall ist.
der Code ist unter:

string strHtml = @"
<html>
  <div>
    <p><strong>Elem_A</strong>String_A1_2 String_A1_2</p>
    <p><strong>Elem_B</strong>String_B1_2 String_B1_2</p>
  </div>
  <div>
    <p><strong>Elem_A</strong>String_A2_2 <String_A2_2> asdas</p>
    <p><strong>Elem_B</strong>String_B2_2 String_B2_2</p>
  </div>
</html>";
HtmlAgilityPack.HtmlDocument objHtmlDocument = new HtmlAgilityPack.HtmlDocument();
objHtmlDocument.LoadHtml(strHtml);
HtmlAgilityPack.HtmlNodeCollection colnodePs = objHtmlDocument.DocumentNode.SelectNodes("//p");
List<string> lststrText = new List<string>();
foreach (HtmlAgilityPack.HtmlNode nodeP in colnodePs)
{
  lststrText.Add(nodeP.InnerHtml);
}

das Problem ist, dass String_A2_2 in Klammern eingeschlossen ist.
so htmlagility Pack kehrt 5 Strings statt 4 im lststrText.
so ist es möglich, htmlagility Pack Rückstellelement 3, wie zu lassen "<strong>Elem_A</strong>String_A2_2 <String_A2_2> asdas"?
oder vielleicht kann ich tun, einige Vorverarbeitung das Element zu schließen?
der aktuelle Inhalt von lststrText ist

lststrText[0] = "<strong>Elem_A</strong>String_A1_2 String_A1_2"  
lststrText[1] = "<strong>Elem_B</strong>String_B1_2 String_B1_2"  
lststrText[2] = ""  
lststrText[3] = ""  
lststrText[4] = "<strong>Elem_B</strong>String_B2_2 String_B2_2"
War es hilfreich?

Lösung

Die meisten HTML-Parser versuchen, eine Arbeits DOM zu bauen, was bedeutet, baumelnde Tags werden nicht akzeptiert. Sie werden in irgendeiner Weise umgewandelt oder geschlossen wird.

Wenn nur die Knoten der Auswahl ist wichtig für Sie, und die Geschwindigkeit und große Datenmengen kein Problem, könnte man all

-Tags mit einem regulären Ausdruck greift statt:

Regex reMatchP = new Regex(@"<(p)>.*?</\1>");
foreach (Match m in reMatchP.Matches(strHtml))
{
   Console.WriteLine(m.Value);
}

Dieser reguläre Ausdruck übernimmt die

-Tags gut ausgebildet sind und geschlossen werden.

Wenn Sie dieses Regex viel in Ihrem Programm ausführen sollten Sie es erklären, wie:

static Regex reMatchP = new Regex(@"<(p)>.*?</\1>", RegexOptions.Compiled);

[Edit: Agility Pack ändern]

Wenn Sie verwenden möchten HtmlAgility packen Sie die PushNodeEnd Funktion in HtmlDocument.cs ändern können:

if (HtmlNode.IsCDataElement(CurrentNodeName()))
{
   _state = ParseState.PcData;
   return true;
}

// new code start
if ( !AllowedTags.Contains(_currentnode.Name) )
{
    close = true;
}
// new code end

Dabei gilt AllowedTags eine Liste aller bekannten Tags wäre. B, p, br, spanne, div, etc

der Ausgang ist nicht 100%, was Sie wollen, aber vielleicht nahe genug?

<strong>Elem_A</strong>String_A1_2 String_A1_2
<strong>Elem_B</strong>String_B1_2 String_B1_2
<strong>Elem_A</strong>String_A2_2 <ignorestring_a2_2></ignorestring_a2_2> asdas
<strong>Elem_B</strong>String_B2_2 String_B2_2

Andere Tipps

könnten Sie verwenden TidyNet das zu tun pre / Post-processing Sie spielen auf. Können Sie Ihre Antwort bearbeiten, zu erklären, warum das würde nicht in Ihrem Fall anwendbar sein?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top