Skip to content

jsonstat/csharp

Repository files navigation

JSON-stat for C# (JSONstat)

CI License Version

⚠️ Experimental / pre-1.0. This library is published under a 0.x (prerelease) version while the public API settles. Expect breaking changes between releases — including patch bumps — until a stable 1.0.0 is tagged. See Versioning and the Changelog.

Read and write JSON-stat v2.0 statistical data in .NET. This library fills the C# gap in the JSON-stat ecosystem and mirrors the read/navigation interface of the JavaScript Toolkit, while deliberately omitting its deprecated APIs (Slice() and toTable()) in favour of their modern replacements (Dice() and Transform()).

  • Status: experimental (0.1.1) — implemented; 25-test xUnit suite targeting .NET 8 (LTS).
  • Target: netstandard2.0 (runs on .NET Framework 4.6.1+, .NET Core 2.0+, .NET 8+); depends on System.Text.Json 8.x. Built and tested on .NET 8 (LTS).
  • Namespace: JSONstat (brand parity with the JS JSONstat() global; type names stay PascalCase).
  • License: Apache-2.0 · Author: Xavier Badosa.

Naming note: .NET style guidelines prefer PascalCase namespaces, so an IDE analyzer may flag JSONstat as a suggestion (not a build error). Because the entry class shares the namespace name, consume it as JSONstat.JSONstat.Parse(...) or using static JSONstat.JSONstat; then Parse(...). The tests live in a sibling namespace (JSONstatTests) precisely to avoid namespace/type shadowing.

Install

dotnet add package JSONstat

Read (Toolkit-parity navigation)

using JSONstat.Models;
using static JSONstat.JSONstat;

var ds = Parse(jsonString).Dataset()!;

ds.Id;                 // ["concept","area","year"]
ds.N;                  // total cells
ds.Dimension("area");                       // by id
ds.Dimension(2);                            // by index
ds.Dimension(DimensionRole.Time);           // by role

ds.Data(0).Value;                                      // by linear index
ds.Data(new[] { 0, 1, 1 }).Value;                      // by dimension indices
ds.Data(new Dictionary<string,string>                  // by dimension/category ids
    { { "area", "ES" }, { "year", "2014" } }).Value;
ds.ValueAt(3);                              // value only (≈ JS Data(id, false))

ds.Dimension("area").Category("ES").Label;  // "Spain"

All three response classes are supported: dataset, collection (response.Items, Item(i), ItemsOf(ResponseClass.Dataset)), and dimension (response.Dimension).

Transform (non-deprecated only)

// Subset by filtering dimension categories (replaces deprecated Slice)
var subset = ds.Dice(DiceFilter.FromObject(
    new Dictionary<string, IReadOnlyCollection<string>> { { "area", new[] { "GR", "PT" } } }));

// Flat list with full per-cell context
var rows = ds.Unflatten<Datum>(ctx => ctx.Datapoint);   // ctx.Coordinates, ctx.N, ctx.Row

// Tabular forms (replaces deprecated toTable)
var table = ds.Transform(new TransformOptions { Type = TransformType.ArrayOfObjects, Status = true });
Console.WriteLine(table.ToJsonString());

Write

using JSONstat.Builders;
using static JSONstat.JSONstat;

var response = new DatasetBuilder()
    .Label("Demo")
    .Dimension("area", d => d.Category(c => c.Ids("GR", "ES", "PT")))
    .Dimension("year", d => d.Category(c => c.Ids("2013", "2014")))
    .Values(1, 2, 3, 4, 5, 6)
    .Status("e")
    .Role(r => r.Metric = new[] { "area" })
    .BuildResponse();

Console.WriteLine(Serialize(response));   // dense value, string status, round-trips through Parse

Sparse values (SparseValues) and all three status forms (Status(string) / StatusArray(...) / StatusObject(...)) are supported; round-trip fidelity is covered by the test suite.

Fetch

using JSONstat.Models;

// Toolkit parity: the JS toolkit's JSONstat(url) maps to LoadAsync(url).
var ds = (await JSONstat.LoadAsync(new Uri("https://example.com/data.json"))).Dataset()!;

LoadAsync(Uri, HttpClient?, CancellationToken) reuses a shared internal HttpClient (pass your own to customize base address, headers, timeout, or handler — e.g. for tests). Synchronous Load(Uri) is also available. Consumers that only Parse pay no HTTP cost.

Scope

In scope Deferred
Dataset read + write JSON-Schema / semantic validation
Full Toolkit navigation CSV/Arrow/Parquet interop (jsonstat-io)
Dice, Unflatten, Transform Deprecated Toolkit APIs (Slice, toTable)
HTTP fetching (Load / LoadAsync)

Repository layout

csharp/
├── README.md            # this file (also the NuGet readme)
├── CHANGELOG.md         # versioned release history
├── API.md               # full API reference (types, methods, properties, enums)
├── JSONstat.sln
├── src/JSONstat/        # netstandard2.0 library
├── tests/JSONstat.Tests/# xUnit (21 tests, 5 fixtures)
└── samples/JSONstat.Samples/

Build & test

dotnet test JSONstat.sln
dotnet run --project samples/JSONstat.Samples

Versioning

This project follows Semantic Versioning. While the major version is 0 (currently 0.1.1), the package is considered experimental: any release may contain breaking changes, including in patch releases. A stable, semver-guaranteed 1.0.0 will be tagged once the API is deemed production-ready.

Releases are tracked in CHANGELOG.md and marked with git tags of the form v0.1.1.

Documents

  • API.md — complete API reference: every public type, method, property, and enum.

About

JSON-stat v2.0 for .NET — toolkit-parity read/write, non-deprecated transforms. Experimental (0.x).

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages