TagChecker 1.0.2

dotnet add package TagChecker --version 1.0.2
                    
NuGet\Install-Package TagChecker -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TagChecker" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TagChecker" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="TagChecker" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TagChecker --version 1.0.2
                    
#r "nuget: TagChecker, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TagChecker@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TagChecker&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=TagChecker&version=1.0.2
                    
Install as a Cake Tool

TagChecker

A .NET library for validating HTML tag structure and reporting parse errors with line/column positions.

Supported target frameworks: net8.0, net9.0, net10.0.

Features

  • Validates start/end tag matching and nesting order
  • Detects missing start or end tags
  • Parses attributes and detects malformed attribute syntax
  • Handles HTML comments (``) and DOCTYPE (<!DOCTYPE ...>)
  • Handles raw-content tags (<script>, <style>) without false parsing on < inside content
  • Validates HTML void-element rules with strict behavior
  • Returns structured error details (ErrorCode, LineNumber, Position)

Clone, Build, and Test

git clone https://github.com/foman/TagChecker.git
cd TagChecker
dotnet restore TagChecker.sln
dotnet build TagChecker.sln -c Release
dotnet test TagChecker.sln -c Release

Install from NuGet

dotnet add package TagChecker

Or in .csproj:

<ItemGroup>
  <PackageReference Include="TagChecker" Version="1.0.0" />
</ItemGroup>

Quick Start

using TagChecker;

var html = "<html><body><div class='x'>Hello</div></body></html>";
var (ok, error) = HtmlTagChecker.Validate(html);

if (ok)
{
    Console.WriteLine("HTML is valid");
}
else
{
    Console.WriteLine($"Error: {error.ErrorCode} at line {error.LineNumber}, col {error.Position}");
}

API

HtmlTagChecker.Validate(string content, ParserOptions? options = null)

Returns:

(bool succeed, TagError tagError)
  • succeed: true when validation passes
  • tagError: null on success; populated on failure

ParserOptions

new ParserOptions
{
    TagNamePatternStrict = true
}
  • TagNamePatternStrict = false (default): compatibility mode
  • TagNamePatternStrict = true: enforces strict tag-name pattern:
    • first character must be a letter (A-Z / a-z)
    • remaining characters can be letters, digits, or hyphen (-)

Behavior Notes

Void elements

TagChecker currently uses strict void-element behavior:

  • <img /> is valid
  • <img> triggers VoidElementNotSelfClosed (strict XML-like rule)
  • </img> triggers VoidElementClosed

Void-element set: area, base, br, col, embed, hr, img, input, link, meta, param, source, track, wbr

Script/style content

For <script> and <style>, content is treated as raw text until matching closing tags. This avoids incorrect parsing when the content contains < characters.

Error Codes

  • TagNotClosed: Missing closing > for a tag
  • NoStartTagFound: Closing tag has no matching opener
  • NoEndTagFound: Opening tag has no matching closer
  • InvalidTag: Invalid tag structure
  • InvalidTagName: Invalid tag name
  • InValidCloseTag: Invalid closing tag format
  • InvalidAttribute: Invalid attribute syntax
  • InvalidAttributeName: Invalid attribute name
  • AttributeNotClosed: Attribute value quote not closed
  • VoidElementClosed: Void element incorrectly closed using </...>
  • VoidElementNotSelfClosed: Void element not self-closed

Examples

Success

var (ok, err) = HtmlTagChecker.Validate("<div><span>Hello</span></div>");
// ok == true
// err == null

Missing end tag

var (ok, err) = HtmlTagChecker.Validate("<div><span>Hello</div>");
// ok == false
// err.ErrorCode == HtmlParseErrorCode.NoStartTagFound (mismatched close)

Strict tag-name validation

var options = new ParserOptions { TagNamePatternStrict = true };
var (ok, err) = HtmlTagChecker.Validate("<1bad></1bad>", options);
// ok == false
// err.ErrorCode == HtmlParseErrorCode.InvalidTagName

Publish to NuGet (lightweight script)

Use the lightweight helper script:

# Dry run (test + pack only)
./scripts/nuget-publish.sh --version 0.2.0 --dry-run

# Real publish
NUGET_API_KEY=*** ./scripts/nuget-publish.sh --version 0.2.0

Optional flags:

  • --skip-tests: skip unit tests before packing
  • --source <url>: custom NuGet source

Publish via GitHub Release (GitHub Actions)

publish.yaml is configured to publish when a GitHub Release is published.

  • Trigger: release.published
  • Version source: release tag (e.g. v0.2.0 → package version 0.2.0)
  • Required secret: NUGET_API_KEY

Quick flow:

  1. Push tag, e.g. v0.2.0
  2. Create a GitHub Release for that tag
  3. GitHub Actions runs build/test/pack/publish automatically

Roadmap (next)

  • Add parser modes: strict (current) vs lenient HTML5 void-element behavior
  • Improve diagnostics with source snippets around error locations
  • Add performance benchmarks for large files and deep nesting
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 104 2/15/2026
1.0.2-alpha 92 2/15/2026
1.0.1 101 2/15/2026
1.0.0 106 2/15/2026