pygixml v0.13.0
pygixml
python · giant · xml · framework

The Python Giant XML framework

pugixml's C++ DOM, an inlined yxml streaming parser, and Cython holding them together — dictify, objectify, jsonify, and a CLI.

Get started See the benchmarks
pip install pygixml
Fastest
wins most of the benchmark suite
Most efficient
lowest peak memory, streaming
<0.5 MB
installed, lightweight
MIT
License
Explore

Everything about pygixml, in two places

API reference and guides on one side, honest performance numbers — refreshed on a schedule, not hand-edited — on the other.

Why pygixml

One package, every way to read XML

Pick the layer that matches what you're actually doing with the file, not one generic tree API forced onto every use case.

Raw DOM
pugixml's tree, directly — XPath 1.0, attributes, namespaces, the whole surface.
dictify
XML → plain dict, same convention as xmltodict — drop-in, not a rewrite.
objectify
Lazy attribute-style access — root.child.grandchild — nothing materialized until touched.
jsonify
Direct XML→JSON, including stream_dump — flat memory, however big the file gets.
Streaming
iterparse / iterfind over yxml — process a file too big to ever load whole, one element at a time.
CLI
pygixml cat, query, stream, convert — XML from a shell pipeline.
Beyond speed

What each library can actually do

Speed and memory aren't the whole story, and pygixml's scope isn't either — it's a Python Giant XML framework, built on pugixml plus a streaming yxml layer for the oversized case. A factual capability comparison, not a benchmark; static, so it lives here rather than in the generated report.

Feature pygixml lxml ElementTree xmltodict xmljson
XPath queries
Selecting nodes with an XPath expression.
✓
Full XPath 1.0 (via pugixml)
✓
Full XPath 1.0, plus EXSLT extensions
~
Small subset: no position(), limited axes
✗ ✗
XSLT transforms
✗ ✓
via libxslt
✗ ✗ ✗
XML Schema (XSD) / DTD validation
✗ ✓
via libxml2
✗ ✗ ✗
Streaming, item-by-item parse
Process one element at a time without holding the whole tree.
✓
iterparse/iterfind (yxml-based)
✓
iterparse
✓
iterparse
✓
item_depth + item_callback
✗
needs an already-built tree
Constant-memory XML → single JSON
Converting a file too large for RAM into one valid JSON document.
✓
jsonify.stream_dump
✗ ✗ ✗
streams dicts to a callback, not one JSON doc
✗
Built-in XML ↔ dict/JSON conversion
✓
dictify (xmltodict-compatible) + jsonify
✗
needs xmljson
✗ ✓
its entire purpose
✓
needs lxml/ElementTree to parse first
YAML / TOON conversion
✓
pygixml convert (optional deps)
✗ ✗ ✗ ✗
Dotted / attribute-style navigation
doc.root.child.grandchild instead of find()/XPath.
✓
objectify
✓
lxml.objectify
✗ ✗
plain dict access only
✗
Command-line tools
✓
cat, query, jsonify, stream, convert
✗ ✗ ✗ ✗
Backend
✓
C++ (pugixml + inlined yxml) via Cython
✓
C (libxml2 / libxslt)
~
C accelerator, pure-Python fallback
✗
pure Python, over stdlib expat
✗
pure Python
Standard library (zero install)
✗ ✗ ✓ ✗ ✗
abi3 / stable-ABI wheels
One compiled wheel across Python minor versions.
✓
cp310-abi3, covers 3.10+
✗
per-Python-version wheels
✓
n/a — ships with the interpreter
✓
n/a — pure Python
✓
n/a — pure Python
Usage

Quick example

The same document, four ways.

import pygixml

doc = pygixml.parse_string("<root><item id='1'>a</item></root>")
root = doc.root()
print(root.child("item").attribute("id").value())  # 1

Ready to try it?

One pip install, no compiler needed on the common platforms.

Installation guide