Skip to main content

Convert LinkML schemas to XSD 1.0/1.1 and Schematron.

Project description

linkml-to-xsd

pipeline coverage release python license

Status 0.x — the mapping is exercised by 200+ tests and at parity on a real production schema, but the Python API may still change before 1.0.

A Python library and CLI that converts LinkML schemas into XML Schema (XSD) — and, for constraints XSD cannot express, Schematron. Built on linkml-runtime's SchemaView, so imports, mixins, slot_usage and inlining are resolved by the reference implementation rather than re-guessed.

Features

  • XSD 1.0 output: classes → xs:complexType + global element; is_axs:extension (UPA-safe); mixins flattened; enums, user types with facets (pattern, minimum_value, maximum_value); cardinality.
  • References vs. inlining follow LinkML semantics: a non-inlined class-range slot with an identifier becomes a reference; inlined/inlined_as_list produce nested elements.
  • Identity constraints: identifierxs:key, unique_keysxs:unique, references → xs:keyref (real referential integrity).
  • Value constraints: @default from literal ifabsent, @fixed from equals_string/equals_number.
  • Documentation & metadata: descriptionxs:documentation, class_uri/slot_uri/enum_uri/meaningxs:appinfo.
  • XSD 1.1 (opt-in): class rules also emitted as xs:assert.
  • Schematron: class rules (precondition ⇒ postcondition) and boolean combinators (any_of/all_of/exactly_one_of/none_of) as XPath assertions.
  • Profiles: the eCH-0296 / Akoma Ntoso annotation vocabulary (xml_element, xml_attribute, xml_namespace, xsd_mixed, xsd_content_model) via --profile akn — proven at parity on the real Fedlex SR-101.
  • Example-XML generation and XSD validation helpers.

Installation

From a checkout:

pip install -e ".[dev]"

Released versions are published to PyPI and this project's GitLab package registry on every vX.Y.Z tag:

# PyPI (recommended)
pip install linkml-xsd

# GitLab package registry
pip install linkml-xsd \
  --index-url https://gitlab.com/api/v4/projects/83894258/packages/pypi/simple

Requires Python ≥ 3.10 (CI tests 3.10 and 3.14). Versions are derived from git tags (setuptools_scm) — no manual version bumps.

No Python at hand (Java/XSLT toolchains)? Use the Docker image published on every release:

docker run --rm -v "$PWD":/work \
  registry.gitlab.com/glueswe/public/linkml:latest /work/schema.yaml -o /work/schema.xsd

Usage

CLI

Two entry points: gen-xsd (the linkml generator convention, like gen-json-schema; see docs/generators/xsd.md) and the richer linkml2xsd group (convert / example / validate).

# linkml-style generator CLI
gen-xsd schema.yaml -o schema.xsd
gen-xsd schema.yaml --xsd-version 1.1 --schematron schema.sch

# Standard LinkML → XSD (targetNamespace derived from the schema id/default_prefix)
linkml2xsd convert schema.yaml -o schema.xsd

# eCH-0296 / Akoma Ntoso profile + a companion Schematron for rules
linkml2xsd convert schema.yaml -o schema.xsd --profile akn --schematron schema.sch

# Example XML instance / validate an instance against an XSD
linkml2xsd example schema.yaml -o example.xml
linkml2xsd validate example.xml --xsd schema.xsd

Python API

from linkml_to_xsd import XSDGenerator, SchematronGenerator, ConversionOptions

options = ConversionOptions(profile="akn", xsd_version="1.1", emit_appinfo=True)
xsd = XSDGenerator("schema.yaml", options=options).generate()

sch_gen = SchematronGenerator("schema.yaml", options=options)
sch = sch_gen.generate() if sch_gen.has_rules() else None

XSDGenerator accepts a file path, inline YAML, a dict, a SchemaDefinition or a SchemaFrontend.

Options (ConversionOptions)

Every genuine mapping choice is a validated field with a default:

Option Default Effect
xsd_version "1.0" "1.1" also emits xs:assert for rules
emit_schematron False (API flag; the CLI uses --schematron)
inlining "linkml" or always_inline / always_reference
reference_style "identifier" or uri (key/idref planned)
emit_value_constraints True facets / @fixed
emit_identity_constraints True xs:key/unique/keyref
emit_documentation / emit_appinfo True / False annotations
multilingual_documentation False split [en] … [de] …-tagged descriptions into per-language xs:documentation
target_namespace None override the derived namespace
profile None e.g. "akn"

Architecture

src/linkml_to_xsd/
  config.py        # ConversionOptions — one toggle per mapping decision
  frontend/        # SchemaFrontend over linkml-runtime SchemaView
  emit/            # XSDGenerator (+ naming, typemap)
  schematron/      # SchematronGenerator
  rules.py         # shared rule → XPath compiler (Schematron + xs:assert)
  profile/         # base (no-op) + akn (eCH-0296 / Akoma Ntoso)
  cli.py  xml_generator.py

See docs/adr/ for architectural decisions (ADR 003 records the move to SchemaView) and docs/LINKML_XSD_MAPPING.md for the full LinkML ↔ XSD element mapping and current status.

Testing

Multi-tier and documented in tests/README.md; docs/TEST_COVERAGE.md is the enforced feature × engine matrix.

Tier Checks
Compliance (tests/compliance/*) one feature per case → XSD compiles, matches its golden, accepts/rejects the right instances
Coverage every case is feature-tagged; baseline features stay covered
Corpus real kitchen_sink.yaml + meta.yaml convert and compile
Property (Hypothesis) random supported schemas always compile
XSTS reference inventories XSD constructs LinkML can never emit
pytest
ruff check src tests && ruff format --check src tests
mypy src/linkml_to_xsd/

python tools/fetch_corpora.py [--xsts]   # opt-in corpora (git-ignored)
python tools/gen_golden.py               # refresh golden XSDs after a change
python tools/coverage_matrix.py          # regenerate docs/TEST_COVERAGE.md

Contributing

See CONTRIBUTING.md — most improvements are data, not code: a new feature mapping is one compliance case + one option + one emitter change.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

linkml_xsd-0.2.0.tar.gz (98.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

linkml_xsd-0.2.0-py3-none-any.whl (45.9 kB view details)

Uploaded Python 3

File details

Details for the file linkml_xsd-0.2.0.tar.gz.

File metadata

  • Download URL: linkml_xsd-0.2.0.tar.gz
  • Upload date:
  • Size: 98.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for linkml_xsd-0.2.0.tar.gz
Algorithm Hash digest
SHA256 cc13a6bc0b48c5f611e4f2e39a3e38bbcbe9a4b4abd08ca98b934fc50b731b9a
MD5 67d1252bf0de7872b209e32a5ae97e05
BLAKE2b-256 fa4babbbbea672abe793291b6c56d4cd4ba7cdd8c59681fa1a1e9173f2e09a39

See more details on using hashes here.

File details

Details for the file linkml_xsd-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: linkml_xsd-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 45.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for linkml_xsd-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b7ea316ea1813d2dc4aca29f63429ca0fa4b804bf42f9aea5b3a44c75e2a73a7
MD5 371dbfa981adb756e758be46f36feae2
BLAKE2b-256 a1ecfc41d2cb6fb42cd4587e2a4afe33c363845c20beb9c0a88e063dc1becd37

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page