How to Convert .drawio Files to Diagram-Design Structured IR: A Complete Guide
Use the drawio_extract.py script to parse any .drawio file—XML, PNG, or SVG—and emit a normalized intermediate representation (IR) as JSON or Markdown.
The diagram-design repository provides a dedicated extraction pipeline that transforms draw.io diagrams into a structured, portable format. Whether your source is raw XML, a PNG with embedded diagram data, or an SVG export, the drawio_extract.py script handles format detection, safe parsing, and canonical shape classification automatically.
Understanding the Conversion Pipeline
The extraction process follows four distinct phases, each implemented in skills/diagram-design/scripts/drawio_extract.py:
1. Format Detection and Loading
The load_mxfile function inspects incoming bytes to determine the source type:
- Raw XML – direct
<mxGraphModel>or<mxfile>content - PNG with embedded XML – scans for
zTXtchunks via_png_embedded_xml - SVG with embedded XML – extracts from XML comments via
_svg_embedded_xml - Base64 + deflate payload – decompresses via
_inflatewith zip-bomb protection
The implementation guards against oversized payloads by raising PayloadTooLarge when decompression exceeds safety limits.
2. XML Parsing and Object Construction
The parse_page function walks the <mxGraphModel> tree and constructs three core dataclasses:
Node– represents shapes with resolved absolute geometry, parent-child depth, and classified shape typeEdge– represents connectors with source/target references and waypoint dataPage– container for nodes and edges with diagram metadata
Shape classification happens via classify_shape, which normalizes draw.io styles to a closed vocabulary including rect, ellipse, icon:aws, and other canonical types.
3. Optional Structural Analysis
The analyze function performs supplementary computations—cycle detection, hub node identification, shape distribution counts—without modifying the core IR structure.
4. Output Generation
Two output formats are available:
- Markdown digest (default) – human-readable summary for quick inspection
- Full JSON (
--jsonflag) – complete machine-readable IR for downstream processing
Running the Extractor: Step-by-Step
Step 1: Locate the Script
cd $(git rev-parse --show-toplevel)/skills/diagram-design/scripts
The extractor lives at skills/diagram-design/scripts/drawio_extract.py relative to the repository root.
Step 2: Extract to JSON
python3 drawio_extract.py path/to/diagram.drawio --json > diagram.ir.json
Omit --json to receive the Markdown digest instead.
Step 3: Inspect the Generated IR
import json
with open('diagram.ir.json', encoding='utf-8') as f:
ir = json.load(f)
# Navigate the structure
first_page = ir['pages'][0]
nodes = first_page['nodes']
edges = first_page['edges']
print(f"Page '{first_page['name']}': {len(nodes)} nodes, {len(edges)} edges")
Step 4: Use with the import-drawio Command
./commands/import-drawio.md path/to/diagram.drawio \
--detail=balanced \
--size=doc-inline \
--format=html \
--output=out/diagram
This command orchestrates the full pipeline: extraction, layout, styling, and final rendering.
Complete Code Examples
Extracting Architecture Diagrams
# From repository root
python3 ./skills/diagram-design/scripts/drawio_extract.py \
./scripts/fixtures/sample-architecture.drawio \
--json > architecture.ir.json
Processing IR Programmatically
import json
from pathlib import Path
ir_path = Path("architecture.ir.json")
data = json.loads(ir_path.read_text(encoding="utf-8"))
# Access page metadata and entities
for page in data["pages"]:
print(f"\nPage: {page['name']}")
print(f" Bounds: {page.get('width')} x {page.get('height')}")
print(f" Nodes: {[n['shape'] for n in page['nodes'][:5]]}...")
print(f" Edges: {len(page['edges'])} connections")
Integrating with Rendering Pipeline
# Full workflow: extract, transform, render
./commands/import-drawio.md ./my-system.drawio \
--detail=minimal \
--size=presentation \
--format=svg \
--output=./exports/system-diagram
Safety and Normalization Features
The drawio_extract.py implementation includes several protective measures:
- XML security – rejects
<!DOCTYPE>and<!ENTITY>declarations before parsing to prevent XXE attacks - Decompression limits – caps inflate operations to prevent zip-bomb resource exhaustion
- Canonical shapes – all draw.io styles map to normalized types, ensuring consistent downstream rendering
These safeguards operate automatically without user configuration.
Key Files and References
| File | Purpose |
|---|---|
skills/diagram-design/scripts/drawio_extract.py |
Core extractor with load_mxfile, parse_page, and classify_shape |
commands/import-drawio.md |
User-facing command interface and orchestration |
scripts/verify-drawio-import.py |
Test harness for validation against fixtures |
skills/diagram-design/SKILL.md |
Visual diagram type definitions |
skills/diagram-design/references/output-spec.md |
Size presets and format specifications |
Summary
- Primary tool:
drawio_extract.pyinskills/diagram-design/scripts/ - Input formats: raw XML, PNG with embedded data, SVG with embedded data, base64+deflate payloads
- Core dataclasses:
Node,Edge,Pagewith resolved geometry and canonical shapes - Output options: Markdown digest (default) or full JSON (
--json) - Safety features: XXE prevention, zip-bomb protection, shape normalization
- Integration path: use directly for IR extraction, or via
import-drawiocommand for full rendering
Frequently Asked Questions
What input formats does the extractor support?
The load_mxfile function accepts raw .drawio XML files, PNG images with embedded mxfile data, SVG exports with diagram comments, and base64-encoded deflate-compressed payloads. The script auto-detects the format by inspecting magic bytes and structure.
How do I prevent extraction from hanging on corrupted files?
The extractor implements explicit safeguards: XML entities and DOCTYPE declarations are rejected before parsing, and decompression operations enforce size limits via PayloadTooLarge exceptions. These protections trigger automatically without configuration.
Can I use the IR without the import-drawio command?
Yes. The JSON output from drawio_extract.py is a self-contained intermediate representation. Parse it with standard JSON libraries and feed pages, nodes, and edges into custom tooling, visualization libraries, or documentation generators.
Where are the shape classification rules defined?
The classify_shape function in drawio_extract.py maps draw.io style strings to canonical types. The closed vocabulary includes geometric primitives (rect, ellipse), cloud service icons (icon:aws, icon:gcp), and connector styles, ensuring downstream renderers receive consistent identifiers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →