2012-06-30 16 views
5

Jestem nowicjuszem w XML/HTML-parsowaniu. Nie znasz nawet właściwych słów, aby przeprowadzić odpowiednie wyszukiwanie duplikatów.Odczytywanie wartości z węzła HTML

mam ten plik HTML, który wygląda tak:

<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> 

teraz muszę 00:00:00, 00:00:29 i I'm great! z niego. Mógłbym go odczytać tak:

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; 
    } 
} 

uzyskać wartości w zmiennych a, b i c. Ale nastąpiła niewielka zmiana w formacie HTML. Teraz wygląda HTML tak:

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

w tym scenariuszu jaki sposób analizowania out 00:00:00, 00:00:29 i I'm great!? Próbowałem to:

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; 
} 

Ale otrzymuję ten błąd: This document already has a 'DocumentElement' node. na linii doc.Load(reader). Jak poprawnie czytać i co powoduje problem? Używam .NET 2.0

+2

Spójrz na [pakiet agresji html] (https://htmlagilitypack.codeplex.com/), wygląda na to, co musisz przetworzyć html. – oleksii

+2

HTML! = XML .... –

+0

@oleksii powinienem naprawdę używać biblioteki stron trzecich, gdy jest dużo w System.Xml? Co więcej nie robię nic związanego z html – nawfal

Odpowiedz

6

Wygląda na to, że masz HTML, który chcesz analizować za pomocą analizatora składni XML. To może być również powód, dla którego uzyskasz wyjątek This document already has a 'DocumentElement' node.: ponieważ masz więcej niż jeden węzeł główny, który jest dozwolony (lub lepiej: tolerowany) w HTML, ale nie XML.

Zamiast tego użyj parsera HTML. Niestety, nie ma nic wbudowanego w środowisko .NET. Musisz wziąć do tego bibliotekę osób trzecich. Bardzo dobrym jest HTML agility pack, o którym już wspomniałem w swoim komentarzu.

Edit:

Od komentarze, mam wrażenie, twój nie są znane z tego, że nie ma bezpośredniego związku między HTML i XML. Grafika pochodzi z here ilustruje to całkiem dobrze:

Relation between SGML, HTML and XML

Ani XML jest podzbiorem języka HTML, ani na odwrót. Tylko jeśli masz ścisły XHTML (rzadko), masz dokument HTML, który można przeanalizować za pomocą analizatora składni XML. Ale pamiętaj, że w kodzie takiego dokumentu XHTML jest jakiś błąd, parser zakończy się niepowodzeniem, podczas gdy zwykła przeglądarka będzie nadal wyświetlać stronę. Również przyszłość XHTML jest całkiem jasne, że teraz nadchodzi HTML5 do życia powoli, ale systematycznie ...

Podsumowując: Aby uniknąć tych wszystkich pułapek, wziąć łatwą drogę i iść do parsera HTML.

+0

Nie ma nic, co można zrobić, aby parsować przy użyciu klas XML .NET? – nawfal

+0

Nie, niestety nie. HTML nie jest podzbiorem XML. Ponadto, ponieważ parsery HTML (również używane w przeglądarkach) są * znacznie * bardziej tolerancyjne, jeśli chodzi o parsowanie nieprawidłowych danych wejściowych, ludzie zaczęli pisać nieprawidłowy kod HTML dla stron internetowych lub po prostu nie dbali o ważność. Jednak parsery XML oczekują * bezwzględnie poprawnego * wejścia, jeśli nie, rezygnują z parsowania i wyrzucają wyjątki, jakie widziałeś. –

+0

Dzięki Philip, rozumiem – nawfal

3

Ponieważ chcesz parsować HTML, możesz użyć WebClient (lub WebBrowser), aby załadować stronę, a następnie użyć DOM HTML do poruszania się po niej. Trzeba dodać odwołanie do Microsoft HTML Object Library (COM) na poniższym przykładzie kodu:

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); 

Próbowałem ładowania HTML do XML przed, a jego zbyt trudne - naprawek niezamknięte znaczniki (jak < BR>), umieszczanie wycinków wokół atrybutów, nadawanie atrybutom bez wartości wartości itp.Ponieważ chciałem następnie użyć XSLT przeciwko niemu, po wczytaniu do HTML DOM i poruszaniu się po nim, tworząc odpowiedni węzeł XML dla każdego węzła HTML. Następnie miałem odpowiednią reprezentację XML kodu HTML.

Powiązane problemy