A dependency-free JSON-to-XML converter written in C23.
The behavior and compatibility cases are ported from
vinitkumar/json2xml. The
implementation is new, pure C, and does not embed Python or a third-party JSON
parser.
- Objects, arrays, strings, numbers, booleans, and null
- XML 1.0 validation and escaping
- UTF-8 and JSON Unicode escape handling, including surrogate pairs
- Type attributes and custom wrapper names
- Configurable root, pretty printing, item wrapping, and list headers
@attrs,@val, and@flatcompatibility- CDATA output with safe
]]>splitting - W3C XPath 3.1 JSON-to-XML mapping
- Library API and
json2xml-ccommand - No runtime dependencies
URL input from the Python command is intentionally not included. HTTPS would
require a TLS dependency, which conflicts with this project's dependency-free
scope. Read remote JSON with the HTTP client appropriate for your application,
then pass the bytes to json2xml_convert.
make
make test
make sanitize
make coverageThe build requires a C23 compiler and CMake. The coverage target uses Clang's
llvm-cov and enforces 100% line and function coverage across production
sources. Branch coverage is reported as an additional metric.
Install the current Rust-enabled Python package in an isolated environment, then run the reproducible in-process comparison:
python3 -m venv .benchmark-venv
.benchmark-venv/bin/pip install 'json2xml[fast]'
make benchmark PYTHON=.benchmark-venv/bin/pythonThe harness refuses to run unless the Python package reports the rust
backend. It verifies byte-for-byte output parity before timing and reports both
complete JSON parse-plus-serialize time and Rust serializer-only time. See
BENCHMARKS.md for the latest recorded run.
./build/json2xml-c --no-pretty -s '{"name":"Ada","active":true}'
./build/json2xml-c data.json -o data.xml
cat data.json | ./build/json2xml-c -
./build/json2xml-c --xpath data.jsonRun json2xml-c --help for all conversion flags.
GitHub Releases provide native CLI archives for:
| Operating system | x86-64 / AMD64 | ARM64 / AArch64 |
|---|---|---|
| Linux | linux-x86_64.tar.gz |
linux-arm64.tar.gz |
| macOS | macos-x86_64.tar.gz |
macos-arm64.tar.gz |
| Windows | windows-x86_64.zip |
windows-arm64.zip |
The x86-64 build works on 64-bit AMD and Intel processors. Linux executables are statically linked; macOS and Windows executables use their operating system's standard runtime.
Download the archive for your system and SHA256SUMS from the
latest release.
Verify the download before installing:
sha256sum -c SHA256SUMS --ignore-missing
# macOS also provides: shasum -a 256 -c SHA256SUMSOn Linux or macOS, extract the archive and copy the executable into PATH:
tar -xzf json2xml-c-*.tar.gz
sudo install -m 0755 json2xml-c-*/bin/json2xml-c /usr/local/bin/json2xml-c
json2xml-c --versionOn Windows, expand the ZIP and copy bin\json2xml-c.exe to a directory in
PATH. The initial macOS and Windows archives are unsigned, so those operating
systems may display an unknown-publisher warning.
Pushing a version tag such as v0.1.0 builds and tests all six native targets,
creates a GitHub release, and attaches the archives and checksum manifest. The
tag version must match both CMakeLists.txt and JSON2XML_VERSION.
#include "json2xml.h"
#include <stdio.h>
#include <string.h>
int main(void)
{
const char json[] = "{\"name\":\"Ada\"}";
json2xml_options options = json2xml_options_default();
json2xml_error error = {0};
char *xml = NULL;
size_t xml_len = 0;
options.pretty = false;
json2xml_status status = json2xml_convert(
json, sizeof(json) - 1, &options, &xml, &xml_len, &error);
if (status != JSON2XML_OK) {
fprintf(stderr, "conversion failed at byte %zu: %s\n",
error.offset, error.message);
return 1;
}
fwrite(xml, 1, xml_len, stdout);
json2xml_free(xml);
return 0;
}The input may contain embedded NUL bytes because its length is explicit. The
returned XML is NUL-terminated for convenience; xml_len remains authoritative.
Release it with json2xml_free.
The C tests use literal expected output derived from the Python project's functional suite. Python-only behavior—arbitrary Python object subclasses, runtime backend selection, URL fetching, and Python callbacks—has no direct C equivalent and is outside this API.
Apache License 2.0. See LICENSE and NOTICE.