2012-06-30 10 views
5

Soy nuevo en XML/HTML-parsing. Ni siquiera sabes las palabras correctas para hacer una búsqueda adecuada de duplicados.Valor de lectura del nodo HTML

que tienen este archivo HTML que se parece a esto:

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

Ahora necesito 00:00:00, 00:00:29 y I'm great! de ella. Podía leer así:

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

consigo los valores de las variables a, y bc. Pero hubo un ligero cambio en el formato HTML. Ahora el HTML se parece a esto:

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

En este escenario ¿Cómo analizo a cabo 00:00:00, 00:00:29 y I'm great!? He intentado esto:

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

Pero me sale este error: This document already has a 'DocumentElement' node. en la línea doc.Load(reader). ¿Cómo leer correctamente y qué está causando el problema? Estoy usando .NET 2.0

+2

Eche un vistazo a [html agility pack] (https://htmlagilitypack.codeplex.com/), parece lo que necesita para analizar html. – oleksii

+2

HTML! = XML .... –

+0

@oleksii ¿Debo usar lib de terceros cuando hay mucho en System.Xml? Además, no estoy haciendo nada relacionado con html – nawfal

Respuesta

6

Parece que tiene HTML que desea analizar con un analizador XML. Esa también puede ser la razón por la cual obtienes la excepción This document already has a 'DocumentElement' node.: porque tienes más de un nodo raíz, que está permitido (o mejor: tolerado) en HTML, pero no en XML.

Use un analizador HTML en su lugar. Desafortunadamente, no hay nada incorporado en .NET Framework. Tienes que tomar una biblioteca de terceros para eso. Una muy buena es la HTML agility pack, que oleksii ya mencionó en su comentario.

Editar:

Desde sus comentarios, tengo la sensación de que su no está familiarizado con el hecho de que no existe una relación directa entre HTML y XML. La gráfica tomada de here ilustra esto muy bien:

Relation between SGML, HTML and XML

Ni es un subconjunto de XML en HTML, ni a la inversa. Solo si tiene XHTML estricto (rara vez el caso), tiene un documento HTML que puede analizarse con un analizador XML. Pero tenga en cuenta que si hay algún error en el código de dicho documento XHTML, el analizador fallará, mientras que un navegador común seguirá mostrando la página. Además, el futuro de XHTML es bastante claro, ahora que HTML5 está viniendo a la vida lenta pero constantemente ...

En resumen: para evitar todos esos obstáculos, tomar el camino fácil e ir a por un analizador de HTML.

+0

No hay nada que se pueda hacer para analizar con las clases .NET XML? – nawfal

+0

No, desafortunadamente no. HTML no es un subconjunto de XML. Además, debido a que los analizadores de HTML (también los que se utilizan en los navegadores) son * mucho * más tolerantes a la hora de analizar entradas no válidas, las personas comenzaron a escribir HTML no válido para sitios web o simplemente no les importaba la validez. Sin embargo, los analizadores XML esperan entradas * estrictamente válidas, si no, dejan de analizar y lanzan excepciones como las que ha visto. –

+0

Gracias Philip, entiendo – nawfal

3

Como quiera analizar HTML, puede usar WebClient (o WebBrowser) para cargar la página y luego usar el HTML DOM para navegar a través de él. Es necesario añadir una referencia a Microsoft HTML Object Library (COM) para el ejemplo de código siguiente:

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

me han tratado HTML carga en XML antes, y todo es demasiado duro - arreglar etiquetas sin cerrar (como < BR>), poniendo comillas alrededor de los atributos, dando un valor a los atributos sin valores, etc.Como quería usar XSLT contra él, después de cargarlo en HTML DOM y navegar a través de él creando el nodo XML correspondiente para cada nodo HTML. Luego tuve una representación XML adecuada del HTML.

Cuestiones relacionadas