Skip to content

Deadpoolhp-4/xml-icon-fixer

Repository files navigation

XML Icon Fixer animated banner
Version badge Flask backend badge Docker ready badge XML validated badge Test suite badge
Turn fragile diagram files into portable, offline-safe, shareable assets.

Visual Tour

Upload interface walkthrough
Processing pipeline walkthrough

Why This Exists

Diagrams created in draw.io / diagrams.net often contain external icon references such as:

https://api.iconify.design/lucide:landmark.svg?color=%23000000

That works until it does not.

In restricted environments, offline setups, enterprise networks, sandboxes, exported bundles, and long-lived documentation, those icons can stop rendering because the diagram still depends on a live external service.

XML Icon Fixer solves that by replacing those external SVG URLs with inline data:image/svg+xml payloads so the final diagram becomes self-contained.

What It Does

  • Detects external Iconify SVG references inside .xml and .drawio files
  • Supports both common Iconify URL forms:
    • collection:icon.svg
    • collection/icon.svg
  • Handles URLs embedded inside Draw.io HTML-escaped cell values like <img src='...'/>
  • Fetches SVGs and converts them into UTF-8 encoded inline data URIs
  • Escapes output safely for XML attribute usage
  • Validates XML before and after processing
  • Supports multi-file upload and raw XML paste mode
  • Returns per-file success and error reporting for batch processing

Why It’s Useful

  • Diagrams render correctly offline
  • Shared files stay portable across machines and environments
  • Sandboxed browsers no longer block external icon loading
  • Documentation becomes more durable and reproducible
  • Teams stop debugging broken visual assets caused by expired or blocked URLs

Quick Start

Option 1: Docker Compose

docker compose up --build

Open:

http://localhost:5000

This starts the web app and persists uploaded and processed files under:

  • ./data/uploads
  • ./data/outputs

Option 2: Local Python Run

python3 -m pip install -r requirements.txt
python3 app.py

Then open:

http://localhost:5000

Docker Setup

The project ships with a buildable Compose service so any user with Docker can run the software directly from the repo:

services:
  xml-icon-fixer:
    image: xml-icon-fixer:latest
    build: .
    container_name: xml-icon-fixer
    ports:
      - "5000:5000"
    volumes:
      - ./data/uploads:/app/uploads
      - ./data/outputs:/app/outputs
    environment:
      - PYTHONUNBUFFERED=1
    restart: unless-stopped

Product Tour

1. Upload Files

Drag and drop one or more .xml / .drawio files into the browser UI.

2. Detect External Icons

The backend scans the XML for Iconify SVG references, including escaped URLs buried inside HTML fragments in mxCell values.

3. Inline the SVGs

Each icon is fetched, validated as real SVG, percent-encoded, and embedded back into the XML as a data: URI.

4. Validate the Result

The updated XML is parsed again to make sure the transformation did not break document structure.

5. Download the Fixed File

Each successfully processed file is returned with a downloadable output link and a replacement count.

Architecture

flowchart LR
    A["User uploads .xml / .drawio"] --> B["Flask app receives content"]
    B --> C["Extract Iconify URLs"]
    C --> D["Fetch SVGs"]
    D --> E["Validate SVG markup"]
    E --> F["Convert to encoded data URI"]
    F --> G["Replace URLs in XML"]
    G --> H["Validate final XML"]
    H --> I["Return downloadable fixed file"]
Loading

Edge Cases Covered

The current implementation is built to handle the kinds of cases that usually break quick XML replacement scripts:

  • HTML-escaped icon URLs such as ', ", &
  • Draw.io cell values containing embedded HTML like <img src='...'>
  • Style-based image references such as image=https://...svg;aspect=fixed
  • Mixed batch uploads where some files succeed and others fail
  • Non-UTF-8 uploads
  • Invalid XML input
  • Invalid or non-SVG icon responses
  • Safe filename handling for downloads and generated outputs

Testing

Run the automated test suite:

python3 -m pytest -q

Current coverage includes:

  • escaped query handling
  • lucide:icon style Iconify URLs
  • slash-style Iconify URLs
  • malformed SVG responses
  • invalid XML rejection
  • partial-success upload flows
  • non-UTF-8 file rejection
  • missing file download behavior

Example Transformation

Before

<mxCell value="&lt;img src=&#39;https://api.iconify.design/lucide:landmark.svg?color=%23000000&#39;/&gt;" />

After

<mxCell value="&lt;img src=&#39;data:image/svg+xml;utf8,%3Csvg...%3E&#39;/&gt;" />

Project Structure

xml-icon-fixer/
├── app.py
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── pytest.ini
├── templates/
│   └── index.html
├── static/
│   ├── script.js
│   └── style.css
└── tests/
    └── test_app.py

Tech Stack

Layer Technology
Backend Flask
Frontend HTML, CSS, JavaScript
Processing Regex + XML validation
Fetching Python standard library (urllib)
Testing Pytest
Deployment Docker, Docker Compose, Gunicorn

Current UI Features

  • drag and drop uploads
  • multiple file support
  • paste-XML processing mode
  • upload progress indicator
  • replacement counts
  • per-file error display
  • downloadable processed outputs

Future Enhancements

  • live diagram preview before download
  • ZIP download for batch results
  • caching for repeated icon URLs
  • duplicate SVG deduplication
  • SVG minification pipeline
  • support for more icon/CDN patterns beyond Iconify
  • optional auth and usage dashboard

Repo Pitch

XML Icon Fixer is a lightweight developer utility that repairs fragile diagram dependencies by converting external Iconify SVG references in Draw.io XML into self-contained inline assets, making diagrams portable, offline-safe, and consistent across restricted environments.

Resume One-Liner

Built a Dockerized Flask tool that converts external SVG icon dependencies in Draw.io XML into inline validated data URIs, enabling reliable offline and sandbox-safe rendering.

Development Commands

Start locally

python3 app.py

Run tests

python3 -m pytest -q

Start with Docker

docker compose up --build

Notes

  • The app currently focuses on Iconify-hosted SVG URLs.
  • Outputs are written to the outputs/ directory in local mode and ./data/outputs in Docker Compose mode.
  • Uploaded files are accepted as .xml and .drawio.
  • The README visuals are stored locally under assets/ so the repo presentation stays self-contained.

Build diagrams once. Open them anywhere.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors