Seleccione todos los elementos DOM con HTMLAgilityPack

.net c# dom html html-agility-pack

Pregunta

He estado buscando preguntas similares y buscando en línea pero parece que no puedo encontrar una solución. Lo que estoy tratando de hacer es seleccionar todos los elementos DOM en orden (etc.) y luego colocarlos en un arraylist o algo así.

actualmente tengo

public void Parse()
    {
        HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();

        // There are various options, set as needed
        //htmlDoc.OptionFixNestedTags = true;

        // filePath is a path to a file containing the html
        htmlDoc.Load("Test.html");

        // Use:  htmlDoc.LoadHtml(xmlString);  to load from a string (was htmlDoc.LoadXML(xmlString)

        // ParseErrors is an ArrayList containing any errors from the Load statement
        if (htmlDoc.ParseErrors != null && htmlDoc.ParseErrors.Count() > 0)
        {
            Console.WriteLine("There was an error parsing the HTML file");
        }
        else
        {
            if (htmlDoc.DocumentNode != null)
            {
                htmlDoc.DocumentNode.Descendants();

                Console.WriteLine("document node not null");
                //HtmlAgilityPack.HtmlNode bodyNode = htmlDoc.DocumentNode.SelectSingleNode("//body");

                foreach (HtmlNode node in htmlDoc.DocumentNode.Descendants())
                {
                    Console.WriteLine(node.Name);
                }
            }
        }
    }

El código de salida pone el nombre del nodo (html, título, imagen, etc.) pero genera las etiquetas de cierre como "#text". Supongo que esto se debe a que las etiquetas comienzan con una "/". ¿Cómo puedo obtener una lectura correcta de todos los elementos DOM?

Respuesta aceptada

"#text" es el nombre de los nodos de texto y las etiquetas de cierre no se representan como algo único en el DOM.

<div><span>foo</span> bar</div>

Te dara arbol como

div
   span
      #text:foo
   #text:bar

Respuesta popular

Sospecho que los elementos #text que viste son saltos de línea en lugar de cerrar la etiqueta. Por ejemplo, esta entrada html:

<div>
    <a href="http://example.org"></a>
</div>

el uso de su código dará salida:

div
#text   <- line break between <div> and <a>
a
#text  <- line break between </a> and </div>

Puede usar esta consulta XPath en su lugar, para obtener todos los elementos que no son nodos de texto sin formato (omitiendo los saltos de línea innecesarios):

foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//*"))
{
    Console.WriteLine(node.Name);
}

Eso significa XPath, seleccione todo descendiente del elemento actual que tenga cualquier nombre ( * ).



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é