texto parser htmlagilitypack examples ejemplo convert c# asp.net html

c# - parser - ¿Cómo convertir Html a texto sin formato?



innerhtml javascript ejemplo (16)

Aquí está mi solución:

public string StripHTML(string html) { var regex = new Regex("<[^>]+>", RegexOptions.IgnoreCase); return System.Web.HttpUtility.HtmlDecode((regex.Replace(html, ""))); }

Ejemplo:

StripHTML("<p class=''test'' style=''color:red;''>Here is my solution:</p>"); // output -> Here is my solution:

Tengo fragmentos de Html almacenados en una tabla. No páginas enteras, sin etiquetas o similares, solo formato básico.

Me gustaría poder mostrar ese HTML solo como texto, sin formatear , en una página determinada (en realidad solo los primeros 30 - 50 caracteres pero ese es el bit fácil).

¿Cómo coloco el "texto" dentro de ese Html en una cadena como texto directo?

Entonces este pedazo de código.

<b>Hello World.</b><br/><p><i>Is there anyone out there?</i><p>

Se convierte en:

Hola Mundo. ¿Hay alguien ahí afuera?


Creo que la manera más fácil es hacer un método de extensión de ''cadena'' (basado en lo que ha sugerido Richard):

using System; using System.Text.RegularExpressions; public static class StringHelpers { public static string StripHTML(this string HTMLText) { var reg = new Regex("<[^>]+>", RegexOptions.IgnoreCase); return reg.Replace(HTMLText, ""); } }

Entonces simplemente use este método de extensión en cualquier variable de ''cadena'' en su programa:

var yourHtmlString = "<div class=/"someclass/"><h2>yourHtmlText</h2></span>"; var yourTextString = yourHtmlString.StripHTML();

Utilizo este método de extensión para convertir los comentarios formateados en html a texto sin formato para que se muestren correctamente en un informe de cristal, ¡y funciona perfecto!


Depende de lo que quiere decir con "html". El caso más complejo sería páginas web completas. También es el más fácil de manejar, ya que puede usar un navegador web en modo texto. Consulte el artículo de Wikipedia que enumera los navegadores web, incluidos los navegadores en modo texto. Lynx es probablemente el más conocido, pero uno de los otros puede ser mejor para sus necesidades.


El HtmlAgilityPack fuente libre y abierta tiene en una de sus muestras un método que convierte de HTML a texto sin formato.

var plainText = ConvertToPlainText(string html);

Alimentarlo con una cadena HTML como

<b> hola mundo! </ b> <br /> <i> soy yo! ! </ i>

Y obtendrás un resultado de texto sin formato como:

hello world! it is me!


La forma más sencilla que encontré:

HtmlFilter.ConvertToPlainText(html);

La clase HtmlFilter se encuentra en Microsoft.TeamFoundation.WorkItemTracking.Controls.dll

El dll se puede encontrar en una carpeta como esta:% ProgramFiles% / Common Files / microsoft shared / Team Foundation Server / 14.0 /

En VS 2015, el dll también requiere referencia a Microsoft.TeamFoundation.WorkItemTracking.Common.dll, ubicado en la misma carpeta.


No escribí pero usé:

using HtmlAgilityPack; using System; using System.IO; using System.Text.RegularExpressions; namespace foo { //small but important modification to class https://github.com/zzzprojects/html-agility-pack/blob/master/src/Samples/Html2Txt/HtmlConvert.cs public static class HtmlToText { public static string Convert(string path) { HtmlDocument doc = new HtmlDocument(); doc.Load(path); return ConvertDoc(doc); } public static string ConvertHtml(string html) { HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(html); return ConvertDoc(doc); } public static string ConvertDoc(HtmlDocument doc) { using (StringWriter sw = new StringWriter()) { ConvertTo(doc.DocumentNode, sw); sw.Flush(); return sw.ToString(); } } internal static void ConvertContentTo(HtmlNode node, TextWriter outText, PreceedingDomTextInfo textInfo) { foreach (HtmlNode subnode in node.ChildNodes) { ConvertTo(subnode, outText, textInfo); } } public static void ConvertTo(HtmlNode node, TextWriter outText) { ConvertTo(node, outText, new PreceedingDomTextInfo(false)); } internal static void ConvertTo(HtmlNode node, TextWriter outText, PreceedingDomTextInfo textInfo) { string html; switch (node.NodeType) { case HtmlNodeType.Comment: // don''t output comments break; case HtmlNodeType.Document: ConvertContentTo(node, outText, textInfo); break; case HtmlNodeType.Text: // script and style must not be output string parentName = node.ParentNode.Name; if ((parentName == "script") || (parentName == "style")) { break; } // get text html = ((HtmlTextNode)node).Text; // is it in fact a special closing node output as text? if (HtmlNode.IsOverlappedClosingElement(html)) { break; } // check the text is meaningful and not a bunch of whitespaces if (html.Length == 0) { break; } if (!textInfo.WritePrecedingWhiteSpace || textInfo.LastCharWasSpace) { html = html.TrimStart(); if (html.Length == 0) { break; } textInfo.IsFirstTextOfDocWritten.Value = textInfo.WritePrecedingWhiteSpace = true; } outText.Write(HtmlEntity.DeEntitize(Regex.Replace(html.TrimEnd(), @"/s{2,}", " "))); if (textInfo.LastCharWasSpace = char.IsWhiteSpace(html[html.Length - 1])) { outText.Write('' ''); } break; case HtmlNodeType.Element: string endElementString = null; bool isInline; bool skip = false; int listIndex = 0; switch (node.Name) { case "nav": skip = true; isInline = false; break; case "body": case "section": case "article": case "aside": case "h1": case "h2": case "header": case "footer": case "address": case "main": case "div": case "p": // stylistic - adjust as you tend to use if (textInfo.IsFirstTextOfDocWritten) { outText.Write("/r/n"); } endElementString = "/r/n"; isInline = false; break; case "br": outText.Write("/r/n"); skip = true; textInfo.WritePrecedingWhiteSpace = false; isInline = true; break; case "a": if (node.Attributes.Contains("href")) { string href = node.Attributes["href"].Value.Trim(); if (node.InnerText.IndexOf(href, StringComparison.InvariantCultureIgnoreCase) == -1) { endElementString = "<" + href + ">"; } } isInline = true; break; case "li": if (textInfo.ListIndex > 0) { outText.Write("/r/n{0}./t", textInfo.ListIndex++); } else { outText.Write("/r/n*/t"); //using ''*'' as bullet char, with tab after, but whatever you want eg "/t->", if utf-8 0x2022 } isInline = false; break; case "ol": listIndex = 1; goto case "ul"; case "ul": //not handling nested lists any differently at this stage - that is getting close to rendering problems endElementString = "/r/n"; isInline = false; break; case "img": //inline-block in reality if (node.Attributes.Contains("alt")) { outText.Write(''['' + node.Attributes["alt"].Value); endElementString = "]"; } if (node.Attributes.Contains("src")) { outText.Write(''<'' + node.Attributes["src"].Value + ''>''); } isInline = true; break; default: isInline = true; break; } if (!skip && node.HasChildNodes) { ConvertContentTo(node, outText, isInline ? textInfo : new PreceedingDomTextInfo(textInfo.IsFirstTextOfDocWritten) { ListIndex = listIndex }); } if (endElementString != null) { outText.Write(endElementString); } break; } } } internal class PreceedingDomTextInfo { public PreceedingDomTextInfo(BoolWrapper isFirstTextOfDocWritten) { IsFirstTextOfDocWritten = isFirstTextOfDocWritten; } public bool WritePrecedingWhiteSpace { get; set; } public bool LastCharWasSpace { get; set; } public readonly BoolWrapper IsFirstTextOfDocWritten; public int ListIndex { get; set; } } internal class BoolWrapper { public BoolWrapper() { } public bool Value { get; set; } public static implicit operator bool(BoolWrapper boolWrapper) { return boolWrapper.Value; } public static implicit operator BoolWrapper(bool boolWrapper) { return new BoolWrapper { Value = boolWrapper }; } } }


No hay un método con el nombre ''ConvertToPlainText'' en HtmlAgilityPack, pero puede convertir una cadena html a CLEAR string con:

HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(htmlString); var textString = doc.DocumentNode.InnerText; Regex.Replace(textString , @"<(.|n)*?>", string.Empty).Replace("&nbsp", "");

Eso es para mi. PERO NO ENCUENTRO UN MÉTODO CON EL NOMBRE ''ConvertToPlainText'' EN ''HtmlAgilityPack''.


No pude usar HtmlAgilityPack, así que escribí una segunda mejor solución para mí

private static string HtmlToPlainText(string html) { const string tagWhiteSpace = @"(>|$)(/W|/n|/r)+<";//matches one or more (white space or line breaks) between ''>'' and ''<'' const string stripFormatting = @"<[^>]*(>|$)";//match any character between ''<'' and ''>'', even when end tag is missing const string lineBreak = @"<(br|BR)/s{0,1}//{0,1}>";//matches: <br>,<br/>,<br />,<BR>,<BR/>,<BR /> var lineBreakRegex = new Regex(lineBreak, RegexOptions.Multiline); var stripFormattingRegex = new Regex(stripFormatting, RegexOptions.Multiline); var tagWhiteSpaceRegex = new Regex(tagWhiteSpace, RegexOptions.Multiline); var text = html; //Decode html specific characters text = System.Net.WebUtility.HtmlDecode(text); //Remove tag whitespace/line breaks text = tagWhiteSpaceRegex.Replace(text, "><"); //Replace <br /> with line breaks text = lineBreakRegex.Replace(text, Environment.NewLine); //Strip formatting text = stripFormattingRegex.Replace(text, string.Empty); return text; }


Para agregar a la respuesta de vfilby, puede realizar una sustitución de RegEx dentro de su código; no hay nuevas clases son necesarias. En caso de que otros novatos como yo estudien esta pregunta.

using System.Text.RegularExpressions;

Entonces...

private string StripHtml(string source) { string output; //get rid of HTML tags output = Regex.Replace(source, "<[^>]*>", string.Empty); //get rid of multiple blank lines output = Regex.Replace(output, @"^/s*$/n", string.Empty, RegexOptions.Multiline); return output; }


Proceso de tres pasos para convertir HTML en texto sin formato

Primero debe instalar el paquete HtmlAgilityPack para HtmlAgilityPack Segundo Crear esta clase

public class HtmlToText { public HtmlToText() { } public string Convert(string path) { HtmlDocument doc = new HtmlDocument(); doc.Load(path); StringWriter sw = new StringWriter(); ConvertTo(doc.DocumentNode, sw); sw.Flush(); return sw.ToString(); } public string ConvertHtml(string html) { HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(html); StringWriter sw = new StringWriter(); ConvertTo(doc.DocumentNode, sw); sw.Flush(); return sw.ToString(); } private void ConvertContentTo(HtmlNode node, TextWriter outText) { foreach(HtmlNode subnode in node.ChildNodes) { ConvertTo(subnode, outText); } } public void ConvertTo(HtmlNode node, TextWriter outText) { string html; switch(node.NodeType) { case HtmlNodeType.Comment: // don''t output comments break; case HtmlNodeType.Document: ConvertContentTo(node, outText); break; case HtmlNodeType.Text: // script and style must not be output string parentName = node.ParentNode.Name; if ((parentName == "script") || (parentName == "style")) break; // get text html = ((HtmlTextNode)node).Text; // is it in fact a special closing node output as text? if (HtmlNode.IsOverlappedClosingElement(html)) break; // check the text is meaningful and not a bunch of whitespaces if (html.Trim().Length > 0) { outText.Write(HtmlEntity.DeEntitize(html)); } break; case HtmlNodeType.Element: switch(node.Name) { case "p": // treat paragraphs as crlf outText.Write("/r/n"); break; } if (node.HasChildNodes) { ConvertContentTo(node, outText); } break; } } }

Al usar la clase anterior con referencia a la respuesta de Judah Himango

En tercer lugar, debe crear el objeto de la clase anterior y usar el método ConvertHtml(HTMLContent) para convertir HTML en texto sin formato en lugar de ConvertToPlainText(string html);

HtmlToText htt=new HtmlToText(); var plainText = htt.ConvertHtml(HTMLContent);


Si habla de pelar etiquetas, es relativamente sencillo si no tiene que preocuparse por cosas como las etiquetas <script> . Si todo lo que necesita hacer es mostrar el texto sin las etiquetas, puede lograr eso con una expresión regular:

<[^>]*>

Si tiene que preocuparse por las etiquetas <script> y similares, entonces necesitará algo un poco más poderoso que las expresiones regulares porque necesita rastrear el estado, más como una Gramática libre de contexto (CFG). Aunque es posible que pueda lograrlo con ''Izquierda a Derecha'' o coincidencia no codiciosa.

Si puede usar expresiones regulares, hay muchas páginas web con buena información:

Si necesita el comportamiento más complejo de un CFG sugeriría utilizar una herramienta de terceros, lamentablemente no conozco uno bueno para recomendar.


Si tiene datos que tienen etiquetas HTML y desea mostrarlos para que una persona pueda VER las etiquetas, use HttpServerUtility :: HtmlEncode.

Si tiene datos que tienen etiquetas HTML y desea que el usuario vea las etiquetas procesadas, entonces muestre el texto tal como está. Si el texto representa una página web completa, use un IFRAME para ello.

Si tiene datos que tienen etiquetas HTML y quiere quitar las etiquetas y solo muestra el texto sin formato, use una expresión regular.


Tenía la misma pregunta, solo mi html tenía un diseño simple conocido, como:

<DIV><P>abc</P><P>def</P></DIV>

Así que terminé usando un código tan simple:

string.Join (Environment.NewLine, XDocument.Parse (html).Root.Elements ().Select (el => el.Value))

Qué salidas:

abc def


Tiene la limitación de no colapsar largos espacios en blanco en línea, pero definitivamente es portátil y respeta el diseño como webbrowser.

static string HtmlToPlainText(string html) { string buf; string block = "address|article|aside|blockquote|canvas|dd|div|dl|dt|" + "fieldset|figcaption|figure|footer|form|h//d|header|hr|li|main|nav|" + "noscript|ol|output|p|pre|section|table|tfoot|ul|video"; string patNestedBlock = $"(//s*?</?({block})[^>]*?>)+//s*"; buf = Regex.Replace(html, patNestedBlock, "/n", RegexOptions.IgnoreCase); // Replace br tag to newline. buf = Regex.Replace(buf, @"<(br)[^>]*>", "/n", RegexOptions.IgnoreCase); // (Optional) remove styles and scripts. buf = Regex.Replace(buf, @"<(script|style)[^>]*?>.*?<//1>", "", RegexOptions.Singleline); // Remove all tags. buf = Regex.Replace(buf, @"<[^>]*(>|$)", "", RegexOptions.Multiline); // Replace HTML entities. buf = WebUtility.HtmlDecode(buf); return buf; }


cadena estática pública StripTags2 (string html) {return html.Replace ("<", "<"). Replace (">", ">"); }

Con esto escapas todo "<" y ">" en una cadena. ¿Es esto lo que quieres?


HTTPUtility.HTMLEncode() está destinado a manejar la codificación de etiquetas HTML como cadenas. Se encarga de todo el trabajo pesado por ti. De la documentación de MSDN :

Si se pasan caracteres como espacios en blanco y signos de puntuación en una secuencia HTTP, podrían malinterpretarse en el extremo receptor. La codificación HTML convierte los caracteres que no están permitidos en HTML en equivalentes entidad-entidad; La decodificación HTML invierte la codificación. Por ejemplo, cuando está incrustado en un bloque de texto, los caracteres < y > se codifican como &lt; y &gt; para la transmisión HTTP.

HTTPUtility.HTMLEncode() , detallado aquí :

public static void HtmlEncode( string s, TextWriter output )

Uso:

String TestString = "This is a <Test String>."; StringWriter writer = new StringWriter(); Server.HtmlEncode(TestString, writer); String EncodedString = writer.ToString();