2012-06-30 15 views
5

Sono nuovo nell'analisi XML/HTML. Non so nemmeno le parole giuste per fare una ricerca corretta per i duplicati.Leggere il valore dal nodo HTML

ho questo file HTML che assomiglia a questo:

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

Ora ho bisogno 00:00:00, 00:00:29 e I'm great! da esso. Ho potuto leggere in questo modo:

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

ottengo i valori delle variabili a, b e c. Ma c'è stato un leggero cambiamento nel formato HTML. Ora il codice HTML si presenta così:

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

In questo scenario come faccio analizzare fuori 00:00:00, 00:00:29 e I'm great!? Ho provato questo:

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

Ma ottengo questo errore: This document already has a 'DocumentElement' node. alla linea doc.Load(reader). Come leggere correttamente e cosa sta causando il problema? Sto usando .NET 2.0

+2

Dai un'occhiata a [html agility pack] (https://htmlagilitypack.codeplex.com/), sembra quello che ti serve per analizzare html. – oleksii

+2

HTML! = XML .... –

+0

@oleksii devo davvero usare lib di terze parti quando ce n'è un sacco sotto System.Xml? Inoltre non sto facendo nulla relativo a html – nawfal

risposta

6

Sembra che tu abbia l'HTML che vuoi analizzare con un parser XML. Questo potrebbe anche essere il motivo per cui ottieni l'eccezione This document already has a 'DocumentElement' node.: perché hai più di un nodo radice, che è consentito (o meglio: tollerato) in HTML, ma non XML.

Utilizzare invece un parser HTML. Sfortunatamente non c'è nulla di integrato nel framework .NET. Devi prendere una libreria di terze parti per questo. Uno molto buono è il HTML agility pack, che oleksii ha già menzionato nel suo commento.

Edit:

Dai vostri commenti, ho la sensazione tuo non ha familiarità con il fatto che non esiste una relazione diretta tra HTML e XML. Il grafico tratto da here illustra questo abbastanza bene:

Relation between SGML, HTML and XML

Né è un sottoinsieme XML di HTML, né viceversa. Solo se hai un XHTML rigoroso (raramente il caso), hai un documento HTML che può essere analizzato con un parser XML. Ma attenzione se c'è qualche errore nel codice di un documento XHTML, il parser fallirà, mentre un browser comune continuerà a visualizzare la pagina. Inoltre, il futuro di XHTML è abbastanza chiaro, ora che HTML5 sta venendo alla vita lentamente ma costantemente ...

Riassumendo: di evitare tutti quei trabocchetti, prendere la strada facile e andare per un parser HTML.

+0

Non c'è nulla che possa essere fatto per analizzare utilizzando le classi XML .NET? – nawfal

+0

No, sfortunatamente no. HTML non è un sottoinsieme di XML. Inoltre, a causa dei parser HTML (anche quelli utilizzati nei browser) che sono * molto * più tolleranti quando si tratta di analizzare input non validi, le persone hanno iniziato a scrivere codice HTML non valido per i siti Web o semplicemente non si sono preoccupati della validità. Tuttavia, i parser XML prevedono un input * strettamente valido *, in caso contrario interromperanno l'analisi e genereranno eccezioni come quelle che hai visto. –

+0

Grazie Philip, capisco – nawfal

3

Poiché si desidera analizzare l'HTML, è possibile utilizzare WebClient (o WebBrowser) per caricare la pagina e quindi utilizzare il DOM HTML per spostarsi all'interno di esso. È necessario aggiungere un riferimento a Microsoft HTML Object Library (COM) per il seguente esempio di codice:

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

ho cercato di caricamento HTML in XML prima, e il suo tutto troppo difficile - fissare i tag non chiusi (come < BR>), mettere le virgolette sugli attributi, dare agli attributi senza valori un valore, ecc.Dato che volevo utilizzare XSLT contro di esso, dopo averlo caricato nel DOM HTML e averlo navigato creando il nodo XML pertinente per ogni nodo HTML. Poi ho avuto una rappresentazione XML corretta dell'HTML.

Problemi correlati