Skip to content

Latest commit

 

History

81 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PolyXML

The High-Performance, Polyglot XML Data-Binding Engine

CI Docs Coverage: 100% Ruff pre-commit License: MIT

crates.io: polyxml crates.io: polyxml-c PyPI: polyxml npm: polyxml Maven Central Go Reference Homebrew ConanCenter PR conda-forge PR vcpkg PR

Rust: 1.80+ Python: 3.12 | 3.13 | 3.14 Node.js: 20 | 22 Java: 22+ Panama Go: 1.22+ C++: 20


Overview

PolyXML is a universal native XML engine engineered in Rust for ultra-fast, streaming XML serialization and deserialization. It bridges raw XML directly to strongly-typed data structures across modern language runtimes with zero unnecessary allocations.

While modern web ecosystems shifted to JSON and Protocol Buffers, mission-critical industries—including defense & aerospace (UCI), finance (ISO 20022, FIXML), and healthcare (HL7)—continue to rely on XML. PolyXML eliminates the single-language silos and performance penalties of legacy XML data-binding tools by providing one optimized, native Rust core for all stacks.


Architecture

                  ┌─────────────────────────────────────┐
                  │          Raw XML Stream             │
                  └──────────────────┬──────────────────┘
                                     │
                                     ▼
                  ┌─────────────────────────────────────┐
                  │            polyxml-core             │
                  │   - quick-xml event reader/writer   │
                  │   - lexical-core scalar parser      │
                  │   - Language-agnostic Schema IR     │
                  │   - Zero-copy streaming state       │
                  └─────────┬───────────────┬───────────┘
                            │               │
           ┌────────────────┼───────────────┼────────────────┐
           ▼                ▼               ▼                ▼
    ┌──────────────┐ ┌─────────────┐ ┌─────────────┐  ┌─────────────┐
    │  Rust / Core │ │   Python    │ │  C++ & Go   │  │ Node / Wasm │
    │ Direct Crate │ │ (PyO3 abi3) │ │(C-ABI / Cgo)│  │  (napi-rs)  │
    └──────────────┘ └─────────────┘ └─────────────┘  └─────────────┘

Key Features

  • ⚡ Blazing Fast: Powered by quick-xml streaming event loop and lexical-core byte-slice parsing. Zero DOM intermediate allocations.
  • 🌊 Streaming Iterator: Parse multi-gigabyte XML documents with $O(1)$ constant memory (<5 MB RAM) via polyxml.iterparse().
  • 🔄 Bidirectional: Full support for both deserialization (XML $\to$ typed models) and serialization (typed models $\to$ XML).
  • 📦 Native Binary Serialization: Ultra-fast MessagePack binary encoding/decoding via polyxml.dumps_binary() and polyxml.loads_binary() for key-value stores (MDBX, LMDB, Redis) and IPC (up to 350,000+ objs/s).
  • 🌐 Polyglot by Design: The core engine is 100% pure Rust with zero Python or language runtime dependencies, ready to be embedded anywhere.
  • 🎯 Full Schema Support: Namespaces, attributes vs. elements, text nodes, xsi:nil, choice, lists, and ISO-8601 date/time scalar types.

🚀 Performance & Benchmarks

PolyXML is benchmarked against the Python and native XML ecosystems on standard, reproducible workloads (full methodology & data).

1. Large Document Throughput (10,000 Catalog Items, 724 KB XML)

Engine Paradigm / Category Implementation Deserialization Latency Deserialization Throughput Serialization Latency Peak RAM
PolyXML Typed Dataclass Rust + PyO3 13.9 ms 51.0 MB/s 7.30 ms 2.0 MB
lxml.etree Untyped DOM C / Cython (libxml2) 10.0 ms 70.5 MB/s <0.1 MB
ElementTree Untyped DOM Python Stdlib C/Python 12.3 ms 57.5 MB/s 7.1 MB
defusedxml Secure DOM Python Defused 27.2 ms 26.0 MB/s 7.1 MB
xmltodict Untyped Dict C (pyexpat) 56.6 ms 12.5 MB/s 79.0 ms 4.8 MB
xsdata Typed Dataclass Pure Python 222.5 ms 3.2 MB/s 282.6 ms 3.3 MB
  • 16.0x faster deserialization & 38.7x faster serialization than xsdata (standard typed dataclasses).
  • 4.1x faster than xmltodict while returning genuine typed dataclasses instead of untyped string dicts.
  • 3.5x lower RAM than Python's standard library xml.etree.ElementTree.

2. Real-Time Micro-Telemetry (Sensor ~100B, Telemetry Commands)

Engine Category Deserialization Latency Serialization Latency Speedup vs Pure Python
PolyXML Typed Dataclass 2.5 μs 1.4 μs 17.1x
PolyXML (Pydantic) Typed Pydantic v2 3.1 μs 1.5 μs 13.7x
lxml.etree Untyped DOM 3.1 μs 13.7x
ElementTree Untyped DOM 4.9 μs 8.7x
xmltodict Untyped Dict 10.3 μs 14.9 μs 4.2x
xsdata Typed Dataclass 43.0 μs 45.0 μs 1.0x (Ref)

Critical telemetry commands and sensor packets deserialize in 2.5 microseconds, beating even C-based DOM parsers (lxml at 3.1 μs).

3. Key-Value Database & Binary IPC (10,000 Entities in MDBX)

When caching parsed models in transactional key-value databases (libmdbx, LMDB, RocksDB) or transferring entity batches across multiprocessing workers, polyxml.dumps_binary() and polyxml.loads_binary() eliminate Python's single-threaded pickle bottlenecks:

Storage Pipeline Dumps Throughput Dumps Latency Loads Throughput Payload Size MDBX Write Speed
CloudPickle + LZ4 (Legacy) 20,609 ops/s 48.5 μs 49,322 ops/s 547 B 18,287 ops/s
Pickle 5 + LZ4 (Stdlib C) 71,954 ops/s 13.9 μs 50,092 ops/s 539 B
PolyXML Binary + LZ4 163,192 ops/s 6.1 μs 64,781 ops/s 252 B 58,781 ops/s
PolyXML Binary (Direct, No LZ4) 213,003 ops/s 4.7 μs 84,673 ops/s 327 B 63,236 ops/s
  • 7.9x faster serialization and 3.2x faster transactional writes into real MDBX.
  • 53.9% smaller storage footprint (252 B vs 547 B per entity).
  • Zero Loss XML Fidelity: Losslessly preserves XmlDate, XmlDateTime, XmlDuration, XmlTime, Decimal, QName, Enum, Path, and Pydantic v2 models.

Language Ecosystem & Packages

Ecosystem / Language Package / Registry Installation Interop Tech Status
Rust (Core) crates.io cargo add polyxml Native Zero-Copy 🟢 Stable
Rust (C-ABI) crates.io cargo add polyxml-c C-ABI Shared Lib 🟢 Stable
Python PyPI pip install polyxml PyO3 (abi3-py312) 🟢 Stable
TypeScript / Node npm npm install polyxml napi-rs Native Addon 🟢 Stable
Java Maven Central <artifactId>polyxml</artifactId> Java 22+ Panama FFI 🟢 Stable
Go Go Reference go get github.com/nth-bailey/PolyXML/bindings/go Cgo (polyxml.h) 🟢 Stable
Modern C++20 / C Conan / vcpkg (polyxml) conan install / vcpkg install polyxml Header-Only C++20 & Native Lib 🟢 Stable
macOS & Linux Homebrew Tap brew install nth-bailey/polyxml/polyxml Native Headers & Dynamic Lib 🟢 Stable

Quickstart Examples

Rust

use std::sync::Arc;
use polyxml::schema::{ModelSchema, FieldSchema, FieldKind, ScalarType, ValueType};
use polyxml::deserialize;

let schema = ModelSchema::builder("User")
    .field(FieldSchema::new("id", b"id", FieldKind::Attribute, ValueType::Scalar(ScalarType::Int)))
    .field(FieldSchema::new("name", b"name", FieldKind::Element, ValueType::Scalar(ScalarType::String)))
    .build();

let xml = br#"<User id="42"><name>Alice</name></User>"#;
let value = deserialize(xml, Arc::clone(&schema))?;

👉 Read the Full Rust Guide & Advanced Examples →

Python

from dataclasses import dataclass, field
import polyxml

@dataclass
class Item:
    id: int = field(metadata={"type": "Attribute"})
    name: str = field(metadata={"type": "Element"})
    price: float = field(metadata={"type": "Element"})

# 1. Deserialize full XML into a typed Python dataclass
item = polyxml.deserialize(b'<Item id="1"><name>Turbine</name><price>99.5</price></Item>', Item)

# 2. Stream huge XML documents with O(1) constant memory (<5 MB RAM)
for item in polyxml.iterparse(open("large_catalog.xml", "rb").read(), Item, tag="Item"):
    print(item.name, item.price)

# 3. Serialize model back to XML
xml_bytes = polyxml.serialize(item, indent=2)

# 4. Zero-GIL binary serialization for key-value databases & IPC
bin_bytes = polyxml.dumps_binary(item)
restored = polyxml.loads_binary(bin_bytes, Item)

👉 Read the Full Python (Dataclasses & Pydantic) Guide →

Modern C++20

#include "polyxml.hpp"

auto schema = polyxml::SchemaBuilder("Sensor")
    .add_attribute("id", "id", POLYXML_SCALAR_INT)
    .add_element("name", "name", POLYXML_SCALAR_STRING)
    .build();

auto val = polyxml::deserialize(R"(<Sensor id="101"><name>Gyro</name></Sensor>)", schema);
std::string name = val.get("name")->as_string().value();

👉 Read the Full Modern C++20 Guide & Examples →

Go

import "github.com/nth-bailey/PolyXML/bindings/go"

builder, _ := polyxml.NewSchemaBuilder("Device")
builder.AddField("id", "id", polyxml.FieldAttribute, polyxml.ScalarInt)
builder.AddField("name", "name", polyxml.FieldElement, polyxml.ScalarString)
schema, _ := builder.Build()

val, err := polyxml.Deserialize(xmlBytes, schema)
name, _ := val.GetField("name").GetString()

👉 Read the Full Go Guide & Struct Adapters →

TypeScript / Node.js

import { deserialize, serialize } from 'polyxml';

const schema = {
  name: 'Item',
  fields: [
    { name: 'id', xmlName: 'id', kind: 'attribute', scalarType: 'int' },
    { name: 'name', xmlName: 'name', kind: 'element', scalarType: 'string' }
  ]
};

const obj = deserialize('<Item id="7"><name>Motor</name></Item>', schema);

👉 Read the Full TypeScript & Node.js Guide →

Java 22+ (Project Panama FFI)

import io.polyxml.PolyXML;

try (var schema = new PolyXML.SchemaBuilder("Sensor")
        .addField("id", "id", PolyXML.FieldKind.ATTRIBUTE, PolyXML.ScalarType.INT)
        .addField("name", "name", PolyXML.FieldKind.ELEMENT, PolyXML.ScalarType.STRING)
        .build()) {

    System.out.println("PolyXML Native Version: " + PolyXML.version());
}

👉 Read the Full Java 22 Panama Guide →


Repository Structure

PolyXML/
├── Cargo.toml                  # Workspace manifest
├── crates/
│   ├── polyxml-core/           # Pure Rust core streaming engine
│   ├── polyxml-python/         # Python bindings (PyO3 + Maturin)
│   ├── polyxml-c/              # Universal C-ABI shared library + polyxml.h
│   └── polyxml-js/             # Node.js & TypeScript bindings (napi-rs)
├── bindings/
│   ├── cpp/                    # Header-only modern C++20 wrapper (polyxml.hpp)
│   ├── go/                     # Go package using Cgo (polyxml.go)
│   └── java/                   # Java 22+ Project Panama FFI (PolyXML.java)

License

Licensed under the MIT License.

About

The universal native XML data-binding engine: high-throughput, bidirectional serialization and schema binding across modern runtimes.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages