HTML Navigation in C#

To navigate HTML in C#, load an HTMLDocument and inspect the DOM with node properties, TreeWalker or NodeIterator, XPath Evaluate(), or QuerySelectorAll(). Use DOM navigation for nearby nodes, XPath for structured document queries, and CSS selectors for tag, class, ID, or attribute matching.

Using the Aspose.HTML for .NET library, you can create applications that analyze and collect information from HTML documents. This article explains how to programmatically extract data from HTML documents with the Aspose.HTML for .NET API.

You will learn:

DOM Navigation

The Aspose.Html.Dom namespace provides APIs that represent and interact with HTML, XML, and SVG documents and are based on the WHATWG DOM specification supported in many modern browsers. The DOM represents a document as a node tree, where each node is part of the document, such as an element, text string, or comment.

We consider how the DOM represents an HTML document in memory and how to use the API for navigation through HTML files. Many approaches can be used for HTML navigation. The following list shows the simplest properties for accessing DOM nodes:

PropertyDescription
FirstChildReturns a reference to the first child node of an element.
LastChildReturns a reference to the last child node of an element.
NextSiblingReturns a reference to the sibling node that immediately follows the current element.
PreviousSiblingReturns a reference to the sibling node that immediately precedes the current element.
ChildNodesReturns a NodeList that contains all children of an element.

Four of the Node class properties, FirstChild, LastChild, NextSibling, and PreviousSibling, each provide a live reference to another element with the defined relationship to the current element if the related element exists. For a complete list of classes and methods represented in the Aspose.Html.Dom namespace, visit the API Reference.

Direct Node Navigation

Using the properties above, you can walk through an HTML document as shown below.

To navigate HTML nodes directly in C#:

  1. Load the source HTML document.
  2. Start from a known node, such as the document element or body element.
  3. Use DOM properties such as FirstChild, ChildNodes, NextSibling, or PreviousSibling.
  4. Read node names, values, attributes, or child nodes according to your extraction task.
 1// Navigate the HTML DOM using C#
 2
 3// Prepare HTML code
 4string html_code = "<span>Hello,</span> <span>World!</span>";
 5
 6// Initialize a document from the prepared code
 7using (HTMLDocument document = new HTMLDocument(html_code, "."))
 8{
 9    // Get the reference to the first child (first <span>) of the <body>
10    Node element = document.Body.FirstChild;
11    Console.WriteLine(element.TextContent); // output: Hello,
12
13    // Get the reference to the whitespace between html elements
14    element = element.NextSibling;
15    Console.WriteLine(element.TextContent); // output: ' '
16
17    // Get the reference to the second <span> element
18    element = element.NextSibling;
19    Console.WriteLine(element.TextContent); // output: World!
20
21    // Set an html variable for the document 
22    string html = document.DocumentElement.OuterHTML;
23
24    Console.WriteLine(html); // output: <html><head></head><body><span>Hello,</span> <span>World!</span></body></html>
25}

Inspect HTML

Aspose.HTML contains methods based on the Element Traversal specification. You can perform a detailed inspection of the document and its elements using the API. The following code sample shows the generalized usage of Element Traversal features.

To inspect HTML elements in C#:

  1. Load the HTML file from the local file system.
  2. Access the document element with DocumentElement.
  3. Move through element children with traversal properties.
  4. Read element names or values while walking through the document tree.
 1// Access and navigate HTML elements in a document using C#
 2
 3// Load a document from a file
 4string documentPath = Path.Combine(DataDir, "html_file.html");
 5
 6using (HTMLDocument document = new HTMLDocument(documentPath))
 7{
 8    // Get the html element of the document
 9    Element element = document.DocumentElement;
10    Console.WriteLine(element.TagName); // HTML
11
12    // Get the last element of the html element
13    element = element.LastElementChild;
14    Console.WriteLine(element.TagName); // BODY
15
16    // Get the first element in the body element
17    element = element.FirstElementChild;
18    Console.WriteLine(element.TagName); // H1
19    Console.WriteLine(element.TextContent); // Header 1
20}

Note: You need to specify the path to the source HTML file in your local file system (documentPath).

The DocumentElement property of the Document class gives direct access to the <html> element of the document, such as html_file.html. The LastElementChild property of the Document class returns the last child element of the <html> element. It is the <body> element. According to the code snippet above, the variable element is overloaded again, and the FirstElementChild property returns the first child of the <body> element. It is the <h1> element.

Implementing a NodeFilter for Images

For more complicated scenarios, when you need to find a node based on a specific pattern, such as getting a list of headers, links, or images, you can use a specialized TreeWalker or NodeIterator object with a custom NodeFilter implementation.

The following example shows how to implement your own NodeFilter to skip all elements except images.

To use a custom NodeFilter for images:

  1. Implement a filter class that accepts only image elements.
  2. Create a TreeWalker or NodeIterator for the loaded document.
  3. Pass the filter instance when creating the walker or iterator.
  4. Iterate through accepted nodes and process the matching image elements.
 1// Filter only <img> elements in HTML tree using C#
 2
 3class OnlyImageFilter : Aspose.Html.Dom.Traversal.Filters.NodeFilter
 4{
 5    public override short AcceptNode(Node n)
 6    {
 7        // The current filter skips all elements, except IMG elements
 8        return string.Equals("img", n.LocalName)
 9            ? FILTER_ACCEPT
10            : FILTER_SKIP;
11    }
12}

Once you implement a filter, you can use HTML navigation as follows:

 1// Implement NodeFilter to skip all elements except images
 2
 3// Prepare HTML code
 4string code = @"
 5    <p>Hello,</p>
 6    <img src='image1.png'>
 7    <img src='image2.png'>
 8    <p>World!</p>";
 9
10// Initialize a document based on the prepared code
11using (HTMLDocument document = new HTMLDocument(code, "."))
12{
13    // To start HTML navigation, we need to create an instance of TreeWalker
14    // The specified parameters mean that it starts walking from the root of the document, iterating all nodes and using our custom implementation of the filter
15    using (ITreeWalker iterator = document.CreateTreeWalker(document, NodeFilter.SHOW_ALL, new OnlyImageFilter()))
16    {
17        while (iterator.NextNode() != null)
18        {
19            // Since we are using our own filter, the current node will always be an instance of the HTMLImageElement
20            // So, we don't need the additional validations here
21            HTMLImageElement image = (HTMLImageElement)iterator.CurrentNode;
22
23            Console.WriteLine(image.Src);
24            // output: image1.png
25            // output: image2.png
26
27            // Set an html variable for the document 
28            string html = document.DocumentElement.OuterHTML;
29        }
30    }
31}

XPath Query

The alternative to HTML navigation is XPath Query, or XML Path Language, often referred to simply as XPath. It is a query language that can be used to query data from HTML documents. XPath is based on a DOM representation of the HTML document and selects nodes by various criteria. The syntax of XPath expressions is quite simple and, importantly, easy to read and support.

The following example shows how to use XPath queries within the Aspose.HTML API.

To select HTML nodes with XPath in C#:

  1. Load the source HTML document.
  2. Create an XPath expression that matches the target nodes.
  3. Evaluate the XPath expression against the document.
  4. Iterate over the selected nodes and read their content or attributes.
 1// How to use XPath to select nodes using C#
 2
 3// Prepare HTML code
 4string code = @"
 5    <div class='happy'>
 6        <div>
 7            <span>Hello,</span>
 8        </div>
 9    </div>
10    <p class='happy'>
11        <span>World!</span>
12    </p>
13";
14
15// Initialize a document based on the prepared code
16using (HTMLDocument document = new HTMLDocument(code, "."))
17{
18    // Here we evaluate the XPath expression where we select all child <span> elements from elements whose 'class' attribute equals to 'happy':
19    IXPathResult result = document.Evaluate("//*[@class='happy']//span",
20        document,
21        null,
22        XPathResultType.Any,
23        null);
24
25    // Iterate over the resulted nodes
26    for (Node node; (node = result.IterateNext()) != null;)
27    {
28        Console.WriteLine(node.TextContent);
29        // output: Hello,
30        // output: World!
31    }
32}

CSS Selector

Along with HTML navigation and XPath, you can use the CSS Selector API that is also supported by Aspose.HTML for .NET. This API is designed to create a search pattern to match elements in a document tree based on CSS Selectors syntax.

In the following example, we use the QuerySelectorAll() method to navigate through an HTML document and find the needed elements. This method takes a query selector as a parameter and returns a NodeList of all elements that match the specified selector.

To select HTML elements with CSS selectors in C#:

  1. Load the HTML document.
  2. Choose a CSS selector that matches the target elements.
  3. Call QuerySelectorAll() with the selector string.
  4. Iterate through the returned NodeList and process matching elements.
 1// Extract nodes Using CSS selector in C#
 2
 3// Prepare HTML code
 4string code = @"
 5    <div class='happy'>
 6        <div>
 7            <span>Hello,</span>
 8        </div>
 9    </div>
10    <p class='happy'>
11        <span>World!</span>
12    </p>
13";
14
15// Initialize a document based on the prepared code
16using (HTMLDocument document = new HTMLDocument(code, "."))
17{
18    // Here we create a CSS Selector that extracts all elements whose 'class' attribute equals 'happy' and their child <span> elements
19    NodeList elements = document.QuerySelectorAll(".happy span");
20
21    // Iterate over the resulted list of elements
22    foreach (HTMLElement element in elements)
23    {
24        Console.WriteLine(element.InnerHTML);
25        // output: Hello,
26        // output: World!
27    }
28}

Common Mistakes and Fixes

ProblemCauseSolution
XPath returns no nodesIncorrect XPath syntax or the expression does not match the loaded document structure.Inspect the loaded DOM, test the expression, and make sure the document is loaded correctly.
QuerySelectorAll() returns an empty listSelector syntax is incorrect, the selected class or ID is different in the loaded HTML, or the wrong element type is used.Use exact CSS selector syntax and verify the HTML structure. HTML element names are case-insensitive, but class and ID selectors are case-sensitive.
Custom NodeFilter never firesThe filter is implemented but not attached to the walker or iterator.Pass the filter instance when creating TreeWalker or NodeIterator.
Traversal code reads whitespace text nodesDOM navigation can encounter text nodes, comments, or whitespace, not only element nodes.Check node type before reading element-specific properties or use traversal APIs that match your extraction needs.

FAQ

Should I use DOM navigation, XPath, or CSS selectors?

Use DOM navigation when you need to walk through nearby nodes step by step. Use XPath for structured document queries and CSS selectors for familiar element matching by tag, class, ID, or attribute.

Does QuerySelectorAll() return one element or many elements?

QuerySelectorAll() returns a NodeList containing all elements that match the specified selector. Iterate through the list to process every matching element.

Can I filter only image elements while navigating HTML?

Yes. Implement a custom NodeFilter, then pass it to TreeWalker or NodeIterator so traversal accepts only the nodes required by your extraction workflow.

Other Platforms

Related Data Extraction Articles

The complete C# examples and data files are available in the Aspose.HTML for .NET GitHub repository.