TagChecker 1.0.2
dotnet add package TagChecker --version 1.0.2
NuGet\Install-Package TagChecker -Version 1.0.2
<PackageReference Include="TagChecker" Version="1.0.2" />
<PackageVersion Include="TagChecker" Version="1.0.2" />
<PackageReference Include="TagChecker" />
paket add TagChecker --version 1.0.2
#r "nuget: TagChecker, 1.0.2"
#:package TagChecker@1.0.2
#addin nuget:?package=TagChecker&version=1.0.2
#tool nuget:?package=TagChecker&version=1.0.2
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:truewhen validation passestagError:nullon success; populated on failure
ParserOptions
new ParserOptions
{
TagNamePatternStrict = true
}
TagNamePatternStrict = false(default): compatibility modeTagNamePatternStrict = true: enforces strict tag-name pattern:- first character must be a letter (
A-Z/a-z) - remaining characters can be letters, digits, or hyphen (
-)
- first character must be a letter (
Behavior Notes
Void elements
TagChecker currently uses strict void-element behavior:
<img />is valid<img>triggersVoidElementNotSelfClosed(strict XML-like rule)</img>triggersVoidElementClosed
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 tagNoStartTagFound: Closing tag has no matching openerNoEndTagFound: Opening tag has no matching closerInvalidTag: Invalid tag structureInvalidTagName: Invalid tag nameInValidCloseTag: Invalid closing tag formatInvalidAttribute: Invalid attribute syntaxInvalidAttributeName: Invalid attribute nameAttributeNotClosed: Attribute value quote not closedVoidElementClosed: 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 version0.2.0) - Required secret:
NUGET_API_KEY
Quick flow:
- Push tag, e.g.
v0.2.0 - Create a GitHub Release for that tag
- 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 | Versions 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. |
-
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 |