J5ml 0.2.0

dotnet add package J5ml --version 0.2.0
                    
NuGet\Install-Package J5ml -Version 0.2.0
                    
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="J5ml" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="J5ml" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="J5ml" />
                    
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 J5ml --version 0.2.0
                    
#r "nuget: J5ml, 0.2.0"
                    
#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 J5ml@0.2.0
                    
#: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=J5ml&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=J5ml&version=0.2.0
                    
Install as a Cake Tool

J5ml

J5ML is a JSON representation of a markup tree.

NuGet

using J5ml;

var node = J5mlDocument.Parse("""["div",{"class":"panel"},"Hello"]""");
// Element { Name = "div", Attrs = { ["class"] = "panel" }, Children = [ Text("Hello") ] }

J5mlDocument.Stringify(node); // ["div",{"class":"panel"},"Hello"]

Markup describes trees. JSON describes data. J5ML is for documents that have to do both at once.

It is JsonML, widened for trees that are not XML. Every valid JsonML document is a valid J5ML document.

What it adds: an attribute value may be any JSON value, including an array or an object, where JsonML's grammar allows only string, number, true, false, and null. And Parse accepts JSON5, so a hand-authored document may carry comments, trailing commas, and unquoted keys:

var node = J5mlDocument.Parse("""
  // authored by hand
  ['Gauge', { percent: 62.5, }]
  """);

J5mlDocument.Stringify(node); // ["Gauge",{"percent":62.5}]

Serialization is always canonical JSON, never JSON5, so anything this package writes is readable by a plain JSON parser. Use ParseJson when JSON5 syntax should be an error.

["Layout", { "constraints": ["Length:1", "Min:0"] }]
["Gauge",  { "style": { "fg": "Green" }, "ratio_bind": "health", "percent": 62.5 }]

Names are preserved verbatim, so Gauge, ratio_bind, data-bind, and svg:circle all survive a round trip unchanged. Nothing is folded to lowercase on the way through, which is a thing HTML-shaped libraries do and this one does not.

The tree

A node is an element or a text node, and the shape is the same one the shared conformance corpus uses:

public sealed class Element : Node
{
    public string Name { get; }
    public IDictionary<string, JsonNode?> Attrs { get; }
    public IList<Node> Children { get; }
}

public sealed class Text : Node
{
    public string Value { get; }
}

An attribute value is a System.Text.Json.Nodes.JsonNode, so it holds any JSON value and keeps its type: a number arrives as a number, a list as a list.

Attribute names are ordered by Unicode code point on the way out, recursively through attribute values, so the same tree serializes identically here and in every other implementation. That ordering is by code point rather than by StringComparer.Ordinal, which compares UTF-16 code units and disagrees with UTF-8 byte order above U+FFFF.

Walking a tree

Traverse visits a node and its descendants, parents before children, handing the visitor the path to each one:

using J5ml;

var tree = J5mlDocument.Parse("""["doc",{},["script",{},"x"]]""");

string? found = null;
J5mlDocument.Traverse(tree, (node, path) =>
{
    if (node is Element { Name: "script" })
    {
        found = J5mlDocument.PathToString(path); // "/0"
        return Walk.Stop;
    }
    return Walk.Continue;
});

Return Walk.Skip to leave a node's children unvisited and carry on with its siblings, or Walk.Stop to end the traversal. An overload taking an Action walks the whole tree when there is nothing to decide.

Attributes are not visited and are not part of a path. An attribute value is JSON rather than markup, so walking into one is a different traversal with different rules. A consumer checking attributes reads Attrs itself and appends the attribute name to the element's path when reporting, because only that consumer knows what it is rejecting.

Not a policy

J5ML does not define which element names are legal, what any of them mean, or whether a document is safe to render. Parse accepts any well-formed tree, <script> included.

A consumer rendering into a medium where markup executes sanitizes it first, because only the consumer knows its own vocabulary and output medium. Traverse is the primitive that check is built on.

For the same reason, serialization escapes only what JSON requires and does not escape <, >, or & for HTML embedding. That is the consumer's call to make at its own edge.

Conformance

This package is asserted against spec/conformance-tests.json, the corpus shared by every J5ML implementation in the repository, rather than against a test suite of its own. See spec/j5ml.md for the format; where the prose and the corpus disagree, the corpus wins.

License

MIT OR Apache-2.0.

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 was computed.  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 was computed.  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.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on J5ml:

Package Downloads
Xript.Runtime

C# runtime for xript — sandboxed JavaScript execution via Jint with manifest-driven bindings and capability enforcement.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 154 7/19/2026