2011-03-24 11 views
8

Recientemente comencé a experimentar con HtmlAgilityPack. No estoy familiarizado con todas sus opciones y creo que estoy haciendo algo mal.Perder el signo 'menos que' en HtmlAgilityPack loadhtml

que tienen una cadena con el siguiente contenido:

string s = "<span style=\"color: #0000FF;\"><</span>"; 

Usted ver que en mi capacidad Tengo un 'menor que' signo. que procesar esta cadena con el siguiente código:

HtmlDocument htmlDocument = new HtmlDocument(); 
htmlDocument.LoadHtml(s); 

Pero cuando hago una mirada rápida y sucia en el lapso de esta manera:

htmlDocument.DocumentNode.ChildNodes[0].InnerHtml 

veo que el lapso está vacía.

¿Qué opción necesito para mantener el signo 'menos que'. Ya probé esto:

htmlDocument.OptionAutoCloseOnEnd = false; 
htmlDocument.OptionCheckSyntax = false; 
htmlDocument.OptionFixNestedTags = false; 

pero sin éxito.

Sé que es HTML no válido. Estoy usando esto para corregir HTML no válido y uso HTMLEncode en los signos 'menos que'

Por favor diríjanme en la dirección correcta. Gracias de antemano

+2

Eso es HTML no válido, por lo que todas las apuestas están apagadas - usted debe estar codificando menos de signos como '' < –

+1

Sé que es HTML válido. Estoy usando esto para corregir HTML no válido y usar HTMLEncode en los signos 'menos que' – TurBas

+0

Hubiera pensado que era difícil para una computadora determinar si un angular determinado es parte de una etiqueta HTML rota o un soporte angular escapado incorrectamente. ¿Ese bit analizado de HTML tiene alguna otra etiqueta? Me sorprendería vagamente si lo destruyera por completo en lugar de convertirlo en otra cosa, pero podría estar equivocado ... – Chris

Respuesta

4

Los paquetes de HTML agilidad detecta esto como un error y crea una instancia HtmlParseError para ello. Puede leer todos los errores usando ParseErrors de la clase HtmlDocument. Por lo tanto, si ejecuta este código:

string s = "<span style=\"color: #0000FF;\"><</span>"; 
    HtmlDocument doc = new HtmlDocument(); 
    doc.LoadHtml(s); 
    doc.Save(Console.Out); 

    Console.WriteLine(); 
    Console.WriteLine(); 

    foreach (HtmlParseError err in doc.ParseErrors) 
    { 
     Console.WriteLine("Error"); 
     Console.WriteLine(" code=" + err.Code); 
     Console.WriteLine(" reason=" + err.Reason); 
     Console.WriteLine(" text=" + err.SourceText); 
     Console.WriteLine(" line=" + err.Line); 
     Console.WriteLine(" pos=" + err.StreamPosition); 
     Console.WriteLine(" col=" + err.LinePosition); 
    } 

Se mostrará este (el texto corregido primero, y detalles acerca del error a continuación):

<span style="color: #0000FF;"></span> 

Error 
code=EndTagNotRequired 
reason=End tag </> is not required 
text=< 
line=1 
pos=30 
col=31 

para que pueda tratar de solucionar este error, como se tiene toda la información requerida (incluida la línea, la columna y la posición del flujo) pero el proceso general de corregir (no detectar) los errores en HTML es muy complejo.

2

corrija las marcas, porque su cadena HTML es válido:

string s = "<span style=\"color: #0000FF;\">&lt;</span>"; 
+0

Sé que no es HTML válido. Estoy usando esto para corregir HTML no válido y uso HTMLEncode en los signos 'menos que' – TurBas

+0

@TurBas: ¿Cuál será el valor de 'InnerHtml' si el texto es' a

+0

Es un <> ... ¿Entonces lo ve como una etiqueta de apertura y lo cierra? ¿Quitando el b? – TurBas

0

cadena "s" es malo html.

string s = "<span style=\"color: #0000FF;\">&lt;</span>"; 

es cierto.

2

Aunque es cierto que el html dado no es válido, HtmlAgilityPack aún debería poder analizarlo. No es un error poco común en la web olvidarse de codificar "<", y si HtmlAgilityPack se utiliza como rastreador, entonces debe anticiparse a html incorrecto. Probé el ejemplo en IE, Chrome y Firefox, y todos muestran el < extra como texto.

me escribió el siguiente método que se puede utilizar para preprocesar la cadena HTML y reemplazar todos los 'sin cerrar' '<' caracteres con "&lt;":

static string PreProcess(string htmlInput) 
{ 
    // Stores the index of the last unclosed '<' character, or -1 if the last '<' character is closed. 
    int lastGt = -1; 

    // This list will be populated with all the unclosed '<' characters. 
    List<int> gtPositions = new List<int>(); 

    // Collect the unclosed '<' characters. 
    for (int i = 0; i < htmlInput.Length; i++) 
    { 
     if (htmlInput[i] == '<') 
     { 
      if (lastGt != -1) 
       gtPositions.Add(lastGt); 

      lastGt = i; 
     } 
     else if (htmlInput[i] == '>') 
      lastGt = -1; 
    } 

    if (lastGt != -1) 
     gtPositions.Add(lastGt); 

    // If no unclosed '<' characters are found, then just return the input string. 
    if (gtPositions.Count == 0) 
     return htmlInput; 

    // Build the output string, replace all unclosed '<' character by "&lt;". 
    StringBuilder htmlOutput = new StringBuilder(htmlInput.Length + 3 * gtPositions.Count); 
    int start = 0; 

    foreach (int gtPosition in gtPositions) 
    { 
     htmlOutput.Append(htmlInput.Substring(start, gtPosition - start)); 
     htmlOutput.Append("&lt;"); 
     start = gtPosition + 1; 
    } 

    htmlOutput.Append(htmlInput.Substring(start)); 
    return htmlOutput.ToString(); 
} 
3

Como mencioné en otra respuesta, la mejor solución que encontré fue realizar un pre-análisis del HTML para convertir los símbolos huérfanos < en su valor codificado en HTML &lt;.

return Regex.Replace(html, "<(?![^<]+>)", "&lt;"); 
Cuestiones relacionadas