2012-06-30 4 views
5

Ich bin neu in XML/HTML-Parsing. Ich kenne nicht einmal die richtigen Worte, um nach Duplikaten zu suchen.Wert von HTML-Knoten lesen

Ich habe diese HTML-Datei, die wie folgt aussieht:

<body id="s1" style="s1"> 
    <div xml:lang="uk"> 
     <p begin="00:00:00" end="00:00:29"> 
      <span fontFamily="SchoolHouse Cursive B" fontSize="18">I'm great!</span> 
     </p> 

Jetzt brauche ich 00:00:00, 00:00:29 und I'm great! von ihm. Ich könnte es wie folgt lesen:

XmlTextReader reader = new XmlTextReader(file); 
while (reader.Read()) 
{ 
    if (reader.NodeType != XmlNodeType.Element) 
     continue; 

    if (reader.LocalName != "p") 
     continue; 

    var a = reader.GetAttribute(0); 
    var b = reader.GetAttribute(1); 

    if (reader.LocalName == "span") 
    { 
     XmlDocument doc = new XmlDocument(); 
     doc.Load(reader); 
     XmlNode elem = doc.DocumentElement.FirstChild; 
     var c = elem.InnerText; 
    } 
} 

I-Werte in Variablen erhalten a, b und c. Aber es gab eine kleine Änderung im HTML-Format. Nun ist die HTML sieht wie folgt aus:

<body id="s1" style="s1"> 
    <div xml:lang="uk"> 
     <p begin="00:00:00" end="00:00:29">I'm great! </p> 

In diesem Szenario wie kann ich 00:00:00 parsen, 00:00:29 und I'm great!? Ich versuchte dies:

XmlTextReader reader = new XmlTextReader(file); 
while (reader.Read()) 
{ 
    if (reader.NodeType != XmlNodeType.Element) 
     continue; 

    if (reader.LocalName != "p") 
     continue; 

    var a = reader.GetAttribute(0); 
    var b = reader.GetAttribute(1); 

    XmlDocument doc = new XmlDocument(); 
    doc.Load(reader); 
    XmlNode elem = doc.DocumentElement.FirstChild; 
    var c = elem.InnerText; 
} 

Aber ich bekomme diese Fehlermeldung: This document already has a 'DocumentElement' node. in Zeile doc.Load(reader). Wie kann ich richtig lesen und was verursacht den Ärger? Ich verwende .NET 2.0

+2

Werfen Sie einen Blick auf [HTML-Agility-Pack] (https://htmlagilypack.codeplex.com/), scheint wie, was Sie brauchen, um HTML zu analysieren. – oleksii

+2

HTML! = XML .... –

+0

@oleksii sollte ich wirklich Libre von Drittanbietern verwenden, wenn es viel unter System.Xml gibt? Außerdem mache ich nichts, was mit html zusammenhängt. – nawfal

Antwort

6

Es sieht aus wie Sie HTML haben, die Sie mit einem XML-Parser analysieren möchten. Das kann auch der Grund sein, warum Sie die Ausnahme This document already has a 'DocumentElement' node. erhalten: weil Sie mehr als einen Wurzelknoten haben, der in HTML erlaubt ist (oder besser: toleriert), aber nicht in XML.

Verwenden Sie stattdessen einen HTML-Parser. Leider ist im .NET-Framework nichts eingebaut. Sie müssen dafür eine Drittanbieter-Bibliothek nehmen. Eine sehr gute ist die HTML agility pack, die Oleksii bereits in seinem Kommentar erwähnt.

Edit:

Von Ihre Kommentare, ich habe das Gefühl, Ihr nicht mit der Tatsache vertraut, dass es keine direkte Beziehung zwischen HTML und XML. Die Grafik genommen von here zeigt dies recht gut:

Relation between SGML, HTML and XML

Weder ist XML eine Teilmenge von HTML, noch umgekehrt. Nur wenn Sie strikt XHTML haben (selten der Fall), haben Sie ein HTML-Dokument, das mit einem XML-Parser analysiert werden kann. Aber beachten Sie, wenn der Code eines solchen XHTML-Dokuments fehlerhaft ist, schlägt der Parser fehl, während ein gewöhnlicher Browser die Seite weiterhin anzeigt. Auch ist die Zukunft von XHTML ziemlich unklar, jetzt, dass HTML5 zum Leben steht vor der Tür langsam, aber stetig ...

Fazit: all diese Fallen zu vermeiden, nehmen den einfachen Weg und gehen für einen HTML-Parser.

+0

klingt Es gibt nichts, was getan werden kann, um mit .NET XML-Klassen zu analysieren. – nawfal

+0

Nein, leider nicht. HTML ist keine Untermenge von XML. Da HTML-Parser (auch die in Browsern verwendeten) sehr viel toleranter sind, wenn es darum geht, ungültige Eingaben zu parsen, haben Leute damit begonnen, ungültigen HTML-Code für Websites zu schreiben oder sich einfach nicht um die Gültigkeit zu kümmern. XML-Parser erwarten jedoch eine * streng gültige * Eingabe, andernfalls beenden sie das Parsen und werfen Ausnahmen, wie Sie es gesehen haben. –

+0

Danke Philip, ich verstehe – nawfal

3

Da Sie HTML analysieren möchten, können Sie WebClient (oder WebBrowser) verwenden, um die Seite zu laden und dann das HTML-DOM zu verwenden, um durch sie zu navigieren. Sie müssen einen Verweis auf Microsoft HTML Object Library (COM) für das folgende Codebeispiel hinzu:

string html; 
    WebClient webClient = new WebClient(); 
    using (Stream stream = webClient.OpenRead(new Uri("http://www.google.com"))) 
    using (StreamReader reader = new StreamReader(stream)) 
    { 
    html = reader.ReadToEnd(); 
    } 
    IHTMLDocument2 doc = (IHTMLDocument2)new HTMLDocument(); 
    doc.write(html); 
    foreach (IHTMLElement el in doc.all) 
    Console.WriteLine(el.tagName); 

Ich habe, bevor sie in XML Laden HTML versucht, und es ist alles zu hart - nicht geschlossene Tags bis zur Festsetzung (wie < BR>), Zitate um Attribute setzen, Attribute ohne Werte einen Wert geben usw.Da ich danach XSLT verwenden wollte, nach dem Laden in das HTML-DOM und Navigieren durch das Erstellen des entsprechenden XML-Knotens für jeden HTML-Knoten. Dann hatte ich eine korrekte XML-Darstellung des HTML.