Stack-Based HTML Validator
A Java application that validates simplified HTML document structure using custom stack data structures.
The project implements both an array-backed stack and a linked-list-backed stack, then uses them to verify whether HTML tags are correctly nested and closed. It also includes sample inputs, validation tests, debugging utilities, and a benchmark for comparing the two stack implementations.
Overview
HTML elements are nested in a last-opened, first-closed order.
For example:
Hello
The
element is opened after
The validator follows this process:
- Read HTML content.
- Scan for tags from left to right.
- Push opening tags onto a stack.
- Ignore valid self-closing and void elements.
- Pop the latest opening tag when a closing tag appears.
- Compare the opening and closing tag names.
- Report mismatched, missing, or unclosed tags.
Features
- Validates nested HTML tag structure
- Detects mismatched closing tags
- Detects closing tags without matching opening tags
- Detects unclosed opening tags
- Detects unclosed HTML comments
- Detects missing closing angle brackets
- Detects empty and invalid tags
- Supports tags containing attributes
- Supports self-closing tags
- Supports standard HTML void elements
- Ignores comments and declarations
- Returns descriptive validation messages
- Reports the character position of structural errors
- Supports interchangeable stack implementations
- Includes validation tests
- Includes performance benchmarking
- Reads HTML input from files
Important Scope
This project validates structural tag nesting.
It is not intended to replace a browser-grade HTML5 parser or a standards-compliance service such as the W3C Nu HTML Checker.
It does not attempt to validate:
- HTML semantics
- Accessibility
- CSS
- JavaScript
- Attribute validity
- Deprecated elements
- Document conformance rules
- Browser error-recovery behaviour
How the Stack Algorithm Works
Consider the following valid HTML:
The stack evolves as follows:
Read
The document is structurally valid because:
- Every closing tag matches the tag at the top of the stack.
- The stack is empty when parsing finishes.
For invalid HTML:
The validator expects when it encounters
Supported HTML Structures
Opening and Closing Tags
Nested Tags
Content
Tags with Attributes
Self-Closing Tags
Comments
Declarations
Void Elements
The validator recognises common HTML void elements that do not require closing tags:
area base br col embed hr img input link meta param source track wbr
Stack Implementations
The validator can operate with two custom stack implementations.
ArrayStack
Stores elements in an array-backed structure.
Typical characteristics:
- Contiguous storage
- Direct indexed access internally
- Fixed or preallocated capacity
- Low per-element allocation overhead
LinkedStack
Stores elements as linked nodes.
Typical characteristics:
- Dynamic growth
- No large contiguous array requirement
- Additional node-reference overhead
- Constant-time insertion and removal at the stack head
Both implementations conform to the same stack abstraction, allowing the validator algorithm to use either implementation without changing its validation logic.
Complexity
Let:
- n represent the length of the HTML input
- t represent the number of recognised tags
- d represent the maximum nesting depth
The validator scans the HTML content sequentially and performs constant-time stack operations for each recognised tag.
Typical complexity:
Time: O(n) Space: O(d)
The maximum auxiliary space depends on the deepest level of nested non-void elements.
Project Structure
StackBasedHTMLValidator/ ├── src/ │ ├── Main.java │ │ │ ├── benchmark/ │ │ └── HTMLValidatorBenchmark.java │ │ │ ├── core/ │ │ ├── HTMLFileReader.java │ │ ├── HTMLValidator.java │ │ └── ValidationResult.java │ │ │ ├── samples/ │ │ └── HTML sample files │ │ │ ├── tests/ │ │ ├── HTMLValidatorDebugTest.java │ │ └── HTMLValidatorTest.java │ │ │ └── util/ │ ├── Stack.java │ ├── ArrayStack.java │ └── LinkedStack.java │ ├── bin/ ├── .settings/ ├── .classpath ├── .project └── README.md
Architecture
HTML File │ ▼ HTMLFileReader │ ▼ HTMLValidator │ ├── ArrayStack │ └── LinkedStack │ ▼ ValidationResult │ ▼ Console Output
HTMLFileReader
Reads HTML content from a file and passes it to the validator.
HTMLValidator
Contains the structural validation algorithm.
It:
- Locates HTML tags
- Extracts tag names
- Detects opening and closing tags
- Handles comments and declarations
- Identifies self-closing and void elements
- Pushes and pops tag names
- Produces validation failures when nesting rules are violated
ValidationResult
Encapsulates the result of validation, including:
- Whether the input is valid
- A descriptive message
- The error position, where applicable
Stack
Defines the common stack operations used by the validator.
ArrayStack
Provides an array-backed implementation of the stack abstraction.
LinkedStack
Provides a linked-node implementation of the stack abstraction.
Getting Started
Prerequisites
Install a Java Development Kit.
Check your installation:
java --version javac --version
Clone the Repository
git clone https://github.com/varundutia/StackBasedHTMLValidator.git cd StackBasedHTMLValidator
Compile
From the repository root:
mkdir -p out javac -d out $(find src -name "*.java")
Run the Demonstration
java -cp out Main
The demonstration validates sample files using both stack implementations.
The current runner compares:
LinkedStack + valid sample LinkedStack + invalid sample ArrayStack + valid sample ArrayStack + invalid sample
Example Output
A valid document may produce:
[LinkedStack] File: valid_simple.html HTML structure is valid.
A mismatched document may produce:
[ArrayStack] File: invalid_mismatch.html Mismatched closing tag. Expected but found
The exact output depends on the included sample files and the ValidationResult string representation.
Using the Validator Programmatically
import core.HTMLValidator; import core.ValidationResult; public class Example { public static void main(String[] args) { String html = "
Hello
Use:
new HTMLValidator(false)
for LinkedStack, or:
new HTMLValidator(true)
for ArrayStack.
Invalid Input Examples
Mismatched Tags
Missing Closing Tag
Content
Unexpected Closing Tag
Unclosed Comment