GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - zig-utils/zig-xml: A small, lenient, allocation-light XML/HTML tokenizer for Zig with HTML5 entity decoding.

BranchesTags
Open more actions menu

Latest commit

 

History

3 Commits
3 Commits

Folders and files

NameName
Last commit message
Last commit date
.github/workflows
.github/workflows
 
 
src
src
 
 
.gitignore
.gitignore
 
 
CHANGELOG.md
CHANGELOG.md
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
SECURITY.md
SECURITY.md
 
 
THIRD_PARTY_NOTICES.md
THIRD_PARTY_NOTICES.md
 
 
build.zig
build.zig
 
 
build.zig.zon
build.zig.zon
 
 
deps.yaml
deps.yaml
 
 
package.json
package.json
 
 
pantry.lock
pantry.lock
 
 

Repository files navigation

zig-xml

A small, lenient, allocation-light XML/HTML tokenizer for Zig, with HTML5 character-reference decoding.

It is a pull tokenizer: you call next() and get one structural event at a time — element open/close, text, CDATA, comments, processing instructions, and declarations — with every name and raw value borrowed from the input. There is no allocation per event (attribute storage is a single reused list), and no implicit entity decoding; decoding is a separate, explicit step.

Leniency is deliberate. zig-xml is built to inspect untrusted, possibly malformed markup (WAF request bodies, scrapers, editor tooling) the way browsers and Go's non-strict encoding/xml do — not to validate well-formedness. Unterminated constructs run to end of input instead of erroring, mismatched close tags are reported verbatim, and unquoted or valueless attributes are accepted. It performs no DTD processing and no external entity resolution, so it is not exposed to XXE or entity-expansion attacks.

Install

With Pantry:

pantry add zig-xml

Then add the module in build.zig:

const xml = b.dependency("xml", .{ .target = target, .optimize = optimize });
your_module.addImport("xml", xml.module("xml"));

Usage

const std = @import("std");
const xml = @import("xml");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();

    var reader = xml.Reader.init(allocator, "<a href=\"?x=1&amp;y=2\">hello</a>");
    defer reader.deinit();

    while (try reader.next()) |event| switch (event) {
        .open, .self_closing => |element| {
            std.debug.print("<{s}>\n", .{element.name});
            for (element.attributes) |attr| {
                // Attribute values are raw; decode when you need the text.
                const value = try xml.decode(allocator, attr.value);
                defer allocator.free(value);
                std.debug.print("  {s} = {s}\n", .{ attr.name, value });
            }
        },
        .text => |raw| {
            const text = try xml.decode(allocator, raw);
            defer allocator.free(text);
            std.debug.print("text: {s}\n", .{text});
        },
        .close => |name| std.debug.print("</{s}>\n", .{name}),
        else => {},
    };
}

Attribute slices (and the Element.attributes list) are valid only until the next call to next() — copy anything you need to retain.

API

  • Reader.init(allocator, input) Reader / reader.deinit()
  • reader.next() !?Event
  • Event — open / self_closing (Element), close (name), text, cdata, comment, processing_instruction, declaration
  • Element{ name, attributes }, with element.attribute(name) ?[]const u8
  • decode(allocator, raw) ![]u8 / decodeInto(&list, allocator, raw) !void
  • entity.lookup(name) ?[2]u21 — the underlying HTML5 named-entity table

Community

For help, discussion about best practices, or any other conversation that would benefit from being searchable:

Discussions on GitHub

For casual chit-chat with others using this package:

Join the zig-utils Discord Server

License

MIT. The bundled HTML5 named-entity table is vendored from Bun (MIT) — see THIRD_PARTY_NOTICES.md.

About

A small, lenient, allocation-light XML/HTML tokenizer for Zig with HTML5 entity decoding.

Topics

html5parsertokenizerxmlzig

Resources

Readme
MIT license

Security policy

Security policy
Activity
Custom properties

Stars

1 star

Watchers

0 watching

Forks

0 forks
Report repository

Releases

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.