m_xml
m_xml is an allocation-free library for reading/writing XML, and serializing/deserializing Zig data structures as XML. It targets a strict subset of XML, meaning not all XML features are supported, but all documents supported by this library are also valid XML 1.0 documents.
Parsed strings borrow slices of the input, and the parser may normalize that input in place. That is to say the input buffer is mutated when deserializing. This, and other constraints on depth and attribute count, allow this library to use only static memory.
It supports deserializing tagged-unions, structs, fixed and bounded collections, optional and default fields and mixed text/element content.
Usage example
const std = @import("std");
const m_xml = @import("m_xml");
const Biography = struct {
date: []const u8,
content: []const u8,
pub const xml = m_xml.schema(@This(), .{
.name = "biography",
.fields = .{ .content = m_xml.text },
});
};
const Person = struct {
id: u64,
age: u8,
name: []const u8,
biography: Biography,
pub const xml = m_xml.schema(@This(), .{
.name = "person",
.fields = .{
.name = m_xml.element,
.biography = m_xml.element,
},
});
};
pub fn main() !void {
const XML = m_xml.Codec(.{ .depth_max = 2, .attributes_max = 2 });
const document =
\\<person id='42' age='36'>
\\ <name>Ada & Co</name>
\\ <biography date='1843'>Designed analytical machines.</biography>
\\</person>
;
var input = document.*;
const person = try XML.parse(&input, Person);
std.debug.print("{d}: {s}, age {d}\n", .{ person.id, person.name, person.age });
std.debug.print(
"{s}: {s}\n",
.{ person.biography.date, person.biography.content },
);
// Parsed strings borrow `input`, so serialization uses separate storage.
var output: [256]u8 = undefined;
const serialized = try XML.serialize(&output, &person, m_xml.Style.compact);
std.debug.print("{s}\n", .{serialized});
}