Obtén todo el elemento del formulario como una cadena usando Html Agility Pack

c# html-agility-pack

Pregunta

Esta es la primera vez que uso Html Agility Pack y enfrento problemas de inmediato.

Al igual que mi título sugiere, quiero obtener un elemento completo como una cadena que incluya elementos internos.

Entonces, por ejemplo, a continuación se encuentra mi html y estoy buscando un elemento de formulario con id aspnetForm

<html>  
<head>  
</head>  
<body>  
  <form name="aspnetForm" id="aspnetForm">
    <div id="div1">  
        <a href="div1-a1">Link 1 inside div1</a>  
        <a href="div1-a2">Link 2 inside div1</a>  
    </div>  
    <a href="a3">Link 3 outside all divs</a>      
    <div id="div2">  
        <a href="div2-a1">Link 1 inside div2</a>  
        <a href="div2-a2">Link 2 inside div2</a>  
    </div> 
  </form> 
</body>  
</html>

Quiero que lo siguiente sea la salida (en cadena)

  <form name="aspnetForm" id="aspnetForm">
    <div id="div1">  
        <a href="div1-a1">Link 1 inside div1</a>  
        <a href="div1-a2">Link 2 inside div1</a>  
    </div>  
    <a href="a3">Link 3 outside all divs</a>      
    <div id="div2">  
        <a href="div2-a1">Link 1 inside div2</a>  
        <a href="div2-a2">Link 2 inside div2</a>  
    </div> 
  </form> 

Por lo general, no me gusta hacer esas preguntas sobre la alimentación con cuchara, pero he estado intentando y buscando, pero no pude obtener una respuesta.

¡Por favor ayuda!

¡Gracias por adelantado!

Respuesta aceptada

Parece que estás buscando HtmlNode.OuterHtml :

//
// Summary:
//     Gets or Sets the object and its content in HTML.
public virtual string OuterHtml { get; }

Así que solo tiene que seleccionar el nodo de su formulario y obtener su propiedad OuterHtml:

HtmlDocument doc = ... // load your HTML
HtmlNode formNode = doc.DocumentNode.SelectSingleNode("//form[@id='aspnetForm']");
string entireElementAsString = formNode.OuterHtml;

ACTUALIZAR

Parece que hay un error muy antiguo en cómo HAP trata las etiquetas de form . O tal vez es una característica !

En cualquier caso, aquí hay una solución:

HtmlNode.ElementsFlags.Remove("form");

Así que esto debería funcionar:

HtmlNode.ElementsFlags.Remove("form");
HtmlDocument doc = ... // load your HTML
HtmlNode formNode = doc.DocumentNode.SelectSingleNode("//form[@id='aspnetForm']");
string entireElementAsString = formNode.OuterHtml;

Respuesta popular

De hecho, buena pregunta, lo suficientemente extraño, todo lo siguiente falla!

Uso de HtmlAgilityPack: ¡aún no se ha podido encontrar una solución!

(tenga en cuenta que también utilizo la biblioteca nuget ScraySharp para obtener la extensión de los selectores Css (ScrapySharp.Extensions)

 string html = @"<html>
        <head>
        </head>
        <body>
          <form name='aspnetForm' id='aspnetForm'>
            <div id='div1'>
                <a href='div1-a1'>Link 1 inside div1</a>
                <a href='div1-a2'>Link 2 inside div1</a>
            </div>
            <a href='a3'>Link 3 outside all divs</a>
            <div id='div2'>
                <a href='div2-a1'>Link 1 inside div2</a>
                <a href='div2-a2'>Link 2 inside div2</a>
            </div>
          </form>
        </body>
        </html>";

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(html);

    string result = string.Empty;

    var formElement = doc.DocumentNode.CssSelect("form").FirstOrDefault();
    var formChildren = formElement.Descendants();

    StringBuilder sb = new StringBuilder();

    if (formChildren != null)
    {
        foreach (var child in formChildren)
        {
            sb.AppendLine(child.InnerHtml);
        }
    }

        //formElement.InnerHtml also returns empty !
        Console.WriteLine(sb.ToString());

Sin embargo, puede lograr esto, mucho más fácil, con AngleSharp (el ángulo agudo parece ser la opción recomendable en estos días, ya que aún se mantiene / desarrolla, mientras que el Paquete de Agilidad Html no).

Usando AngleSharp - funciona

 HtmlParser parser = new HtmlParser();
 var parsedDoc = parser.Parse(html);
 Console.WriteLine(parsedDoc.QuerySelector("form").InnerHtml);

Salida (usando AngleSharp):

introduzca la descripción de la imagen aquí



Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué