Version: 0.1.112
Python library and CLI for loading Eclipse EMF .ecore metamodels and instance files (XMI/XML) using pyecore.
python -m pip install -e .emf-read --ecore <path> [--instance <path>] [--dump-metamodel] [--dump-metamodel-json <path>] \
[--export-metamodel-mermaid <path>] [--export-metamodel-plantuml <path>] [--export-metamodel-gml <path>] \
[--metamodel-include-references] [--dump-instances] [--dump-instances-json <path>] [--dump-instances-filter <expr>] \
[--dump-model] [--dump-model-json <path>] [--export-json <path>] \
[--export-edges <path>] [--export-paths <path>] [--export-path-ids <path>] \
[--export-mermaid <path>] [--export-plantuml <path>] [--export-gml <path>] \
[--export-instance <path>] [--include-classes <list>] [--exclude-classes <list>] [--prune-include-supertypes] [--prune-strip-refs] [--prune-serialize-defaults] [--prune-no-containers] \
[--prune-dry-run] [--prune-dry-run-json <path>] \
[--neighbors-from <expr>] [--neighbors <n>] \
[--filter-expr <expr>] [--expand-from <expr>] [--expand-depth <n>] \
[--expand-classes <list>] [--verbose]
xsd-enrich --ecore <path> --instance <path> --xsd <path> --output <path> [--map <path>] [--trace-name <name>] [--verbose]Dump metamodel summary (no instance required):
emf-read --ecore /var/software/input/ISO20022.ecore --dump-metamodelExport metamodel graph (inheritance + containment references):
emf-read --ecore /var/software/input/ISO20022.ecore --export-metamodel-mermaid /tmp/iso20022_metamodel.mmdDump metamodel to JSON:
emf-read --ecore /var/software/input/ISO20022.ecore --dump-metamodel-json /tmp/metamodel.jsonMetamodel JSON includes package hierarchy (subpackages) and class references with target type, cardinality, and containment.
Load instance, dump summary, and export JSON/edges:
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--dump-instances \
--export-json /tmp/iso20022.json \
--export-edges /tmp/iso20022_edges.csvVerbose logging:
emf-read --ecore /var/software/input/ISO20022.ecore --dump-metamodel --verboseFilter exports with a tiny expression language:
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--filter-expr "is_kind_of('BusinessComponent') and registrationStatus == 'REGISTERED'" \
--export-json /tmp/business_components.json \
--export-edges /tmp/business_components_edges.csvFilter using helper functions (include all BusinessComponent subclasses plus BusinessAssociationEnd):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--filter-expr "is_kind_of('BusinessComponent') or is_class('BusinessAssociationEnd')" \
--export-mermaid /tmp/business_components_with_assoc.mmdNeighborhood expansion from a seed (6 hops, containment + references):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--neighbors-from "name == 'Account'" \
--neighbors 6 \
--export-mermaid /tmp/account_neighborhood.mmdNeighborhood expansion with class filtering:
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--neighbors-from "name == 'Account'" \
--neighbors 6 \
--filter-expr "is_kind_of('BusinessComponent') or is_class('BusinessAssociationEnd')" \
--export-mermaid /tmp/account_neighborhood_filtered.mmdExport a filtered instance resource (XMI):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--export-instance /tmp/filtered.iso20022 \
--include-classes BusinessComponent,BusinessAssociationEnd \
--exclude-classes BusinessProcess \
--prune-include-supertypes \
--prune-strip-refs \
--prune-serialize-defaultsPreview pruning impact without writing an instance file:
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--include-classes BusinessComponent,BusinessAssociationEnd \
--exclude-classes BusinessProcess \
--prune-dry-run \
--prune-dry-run-json /tmp/prune_preview.jsonEnrich an XSD with xmi:id annotations:
xsd-enrich \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--xsd auth.016.001.03.xsd \
--output /tmp/auth.016.001.03.enriched.xsdUse --verbose to log per-element annotation status (annotated/missing).
Trace a specific XSD name during mapping:
xsd-enrich \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--xsd auth.016.001.03.xsd \
--output /tmp/auth.016.001.03.enriched.xsd \
--trace-name UnderlyingIdentification2ChoiceThe enrichment adds xs:annotation/xs:appinfo entries for xmi:id, definition, businessElementName, businessComponentName, businessElementId, businessComponentId, and, when a parent exists, parent (the parent object's XMI id, or its name if the id is missing). It also annotates xs:schema with the messageDefinitionIdentifier and its parts when the targetNamespace matches.
Optional mapping file (--map) can specify preferred EClass matches by XSD kind:
{
"complexType": ["MessageDefinition", "MessageComponent", "MessageComponentType", "ChoiceComponent"],
"simpleType": ["DataType"],
"element": ["MessageElement", "MessageBuildingBlock", "MessageAssociationEnd"],
"attribute": ["MessageAttribute"]
}Expand the graph from a matching start node (depth 2):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--expand-from "eclass == 'BusinessComponent' and name == 'Account'" \
--expand-depth 2 \
--export-json /tmp/account_graph.json \
--export-edges /tmp/account_graph_edges.csvWrite expansion paths (XPath-like, name-only) to a text file:
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--expand-from "eclass == 'BusinessComponent' and name == 'Account'" \
--expand-depth 2 \
--export-paths /tmp/account_paths.txtWrite expansion path IDs (id-only paths that mirror expansion):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--expand-from "eclass == 'BusinessComponent' and name == 'Account'" \
--expand-depth 2 \
--export-path-ids /tmp/account_path_ids.txtRestrict expansion to specific classes:
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--expand-from "eclass == 'BusinessComponent' and name == 'Account'" \
--expand-depth 4 \
--expand-classes BusinessAssociationEnd,BusinessAttribute,BusinessComponent \
--export-paths /tmp/account_paths_limited.txtDump model summary (object counts by class):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--dump-modelDump model summary to JSON:
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--dump-model-json /tmp/model.jsonDump instances grouped by class to JSON:
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--dump-instances-json /tmp/instances_by_class.jsonDump filtered instances grouped by class to JSON:
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--dump-instances-json /tmp/account_instances.json \
--dump-instances-filter "eclass == 'BusinessComponent' and name == 'Account'"Export a Mermaid diagram for BusinessComponent instances (labelled by name):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--filter-expr "is_kind_of('BusinessComponent')" \
--export-mermaid /tmp/business_components.mmdExport a PlantUML class diagram for BusinessComponent instances (labelled by name):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--filter-expr "is_kind_of('BusinessComponent')" \
--export-plantuml /tmp/business_components.pumlExport a GML graph for BusinessComponent instances (labelled by name):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--filter-expr "is_kind_of('BusinessComponent')" \
--export-gml /tmp/business_components.gmlModel JSON includes per-class attribute/reference definitions with target type, cardinality, and containment.
Combine filter and expansion (expand first, then filter results):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--expand-from "eclass == 'BusinessComponent' and name == 'Account'" \
--expand-depth 3 \
--filter-expr "eclass == 'BusinessRole'" \
--export-json /tmp/account_roles.jsonUnbounded expansion (use with care on large models):
emf-read \
--ecore /var/software/input/ISO20022.ecore \
--instance /var/software/input/20250424_ISO20022_2013_eRepository.iso20022 \
--expand-from "eclass == 'BusinessComponent' and name == 'Account'" \
--expand-depth -1 \
--export-edges /tmp/account_all_edges.csvFilter expression variables:
eclass,nsuri,id,ID,local_id,pathattrs(dict of attribute values)- attribute names as direct variables (e.g.,
name,registrationStatus) - helpers:
is_class('Foo'),is_kind_of('BusinessComponent')
Patterns you can use in --filter-expr:
- Exact class match:
is_class('BusinessAssociationEnd') - Subclass match:
is_kind_of('BusinessComponent') - Attribute equality:
registrationStatus == 'REGISTERED' - Combined conditions:
is_kind_of('BusinessComponent') and name == 'Account' - Set membership:
eclass in ('BusinessComponent', 'BusinessAssociationEnd')
A list of objects with:
id: XMI id if present, otherwise stable id per run (based on traversal order)local_id: stable id per run (always present)ID: XMI id if present, otherwiselocal_ideClass: class namensURI: package nsURIattributes: scalar or list attribute valuescontainment: list of child ids (containment references)references: dict of non-containment reference name -> list of target idspath: containment path (e.g.,/Repository[0]/messages[12])
Columns:
src_id,src_classfeaturedst_id,dst_classcontainment(true/false)
from emf_reader.loader import load_metamodel, load_instance
from emf_reader.export import export_json
rset, packages = load_metamodel("/var/software/input/ISO20022.ecore")
resource = load_instance("/var/software/input/20250424_ISO20022_2013_eRepository.iso20022", rset)
export_json(resource.contents, "/tmp/iso20022.json")