Purpose

LutaML aims to be a unified data model accessor that allows parsing data models in multiple languages, including:

  • EXPRESS (EXPRESS Language Foundation, ISO 10303-11)

  • Enterprise Architect UML models in QEA format or exported as OMG XMI

  • UML in LutaML format

Install

With bundler, in Gemfile:

gem "lutaml"

Directly:

$ gem install lutaml

Documentation

Complete documentation is available at https://lutaml.github.io/lutaml/

The documentation includes:

You can also build and browse the documentation locally:

cd docs
bundle install
bundle exec jekyll serve
# Open http://localhost:4000/lutaml/

Usage

Parsing

The Lutaml::Parser.parse method provides a single point of entry for parsing data model files, including:

  • EXPRESS files with .exp extension

  • YAML Compressed EXPRESS CACHE files

  • QEA files with .qea extension (Enterprise Architect databases)

  • XMI files with .xmi extension

  • XML files with .xml extension

  • LutaML files with .lutaml extension

Depending on the input file type, Lutaml::Parser.parse returns:

  • Expressir::Express::Model::Repository for EXPRESS files

  • Expressir::Express::Cache for EXPRESS CACHE files

  • Lutaml::Uml::Document for QEA files (returned as single-element array)

  • Lutaml::Uml::Document for XMI files

  • Lutaml::Uml::Document for XML files

  • Lutaml::Uml::Document for LutaML files

Examples to use the Lutaml::Parser.parse:

require "lutaml"

# example.exp is an EXPRESS schema file
model = Lutaml::Parser.parse([File.new("example.exp")])
# => returns Expressir::Express::Model::Repository model

# example.exp.yaml is an EXPRESS cache file created with Expressir
model = Lutaml::Parser.parse([File.new("example.exp.yaml")], ::Lutaml::Parser::EXPRESS_CACHE_PARSE_TYPE)
# => returns Expressir::Express::Cache model

# example.xmi is an XMI file
model = Lutaml::Parser.parse([File.new("example.xmi")])
# => returns Lutaml::Uml::Document model

# example.xml is an XML file
model = Lutaml::Parser.parse([File.new("example.xml")])
# => returns Lutaml::Uml::Document model

# example.lutaml is an LutaML file
model = Lutaml::Parser.parse([File.new("example.lutaml")])
# => returns Lutaml::Uml::Document model

# example.yaml is an LutaML YAML file
model = Lutaml::Parser.parse([File.new("example.yaml")])
# => returns Lutaml::Uml::Document model

Working with UML

General

Lutaml supports various UML formats and unifies them under a common data model: Lutaml::Uml::Document.

Lutaml supports the following UML formats:

  • Enterprise Architect QEA files (.qea extension)

  • Enterprise Architect exported XMI files (.xmi extension)

  • Enterprise Architect exported XML files (.xml extension)

  • LutaML UML files (.lutaml extension)

LutaML UML

LutaML UML is a simple, human-readable representation of UML models.

The syntax is described in LutaML UML syntax.

Enterprise Architect

Enterprise Architect is a popular UML modeling tool by Sparx Systems. It supports exporting UML models in XMI and XML formats.

Diagram generation

LutaML Diagrams

LutaML Diagram is a lightweight textual syntax for defining model diagrams.

The syntax is described in LutaML diagram syntax.

A CLI is provided to generate diagrams from LutaML DSL files:

# Generate diagrams from LutaML DSL files
$ lutaml -o . test.lutaml
$ lutaml -o assets -t png test.lutaml

General

LutaML provides comprehensive command-line interfaces for working with data models and UML repositories.

UML repository commands (for XMI, QEA, and LUR files):

The lutaml uml command suite provides a complete interface for working with UML models. See [CLI commands reference](#cli-commands-reference) for details.

# Build LUR package from XMI or QEA
$ lutaml uml build model.xmi -o model.lur
$ lutaml uml build project.qea -o project.lur

# Explore and query
$ lutaml uml ls model.lur
$ lutaml uml tree model.lur --depth 2
$ lutaml uml search model.lur "Building"
$ lutaml uml stats model.lur

# Export and document
$ lutaml uml export model.lur --format csv -o classes.csv
$ lutaml uml build-spa model.lur -o docs/index.html
$ lutaml uml serve model.lur --port 8080

# Interactive exploration
$ lutaml uml repl model.lur

Thin wrapper principle

The CLI is designed as a thin wrapper around the Ruby API. Every CLI command directly maps to Ruby API methods, making it easy to:

  • Transition from CLI to programmatic usage

  • Understand what the CLI does by reading the API documentation

  • Script complex workflows using Ruby when needed

Example 1. CLI to API mapping example
# CLI command
$ lutaml uml build model.xmi -o model.lur

Equivalent Ruby code:

require "lutaml/xmi"

repo = Lutaml::UmlRepository::Repository.from_xmi("model.xmi")
repo.export_to_package("model.lur")

UML support

QEA Direct Database Parsing

LutaML supports direct parsing of Enterprise Architect .qea files (SQLite databases) without requiring XMI export. This provides significant performance improvements and access to EA-specific metadata.

What are QEA files?

QEA (Quantified EA) files are Enterprise Architect’s native database format based on SQLite. They contain the complete UML model including:

  • Packages, classes, attributes, operations

  • Associations and generalizations

  • Diagrams and diagram elements

  • EA-specific metadata (stereotypes, tagged values, etc.)

Why direct parsing?

Direct QEA parsing offers several advantages over XMI:

  • Performance: 10-20x faster than XMI parsing

  • No export step: Parse directly from EA database

  • EA metadata: Access to EA-specific information not available in XMI

  • Memory efficient: Streams data from SQLite without loading entire file

Parser API usage

require "lutaml"

# Parse QEA file directly
document = Lutaml::Parser.parse([File.new("model.qea")]).first
# => returns Lutaml::Uml::Document

# Use with UmlRepository
repo = Lutaml::UmlRepository::Repository.new(document: document)

# Query the model
classes = repo.find_classes_by_stereotype("featureType")

QEA module API

The Lutaml::Qea module provides direct access to QEA parsing:

require "lutaml/qea"

# Parse QEA file
document = Lutaml::Qea.parse("model.qea")

# With options
document = Lutaml::Qea.parse("model.qea",
  include_diagrams: true,
  validate: true
)

# Load database for low-level access
database = Lutaml::Qea.load_database("model.qea") do |table, current, total|
  puts "Loading #{table}: #{current}/#{total}"
end

# Get quick statistics
info = Lutaml::Qea.database_info("model.qea")
puts info  # => {"objects" => 693, "attributes" => 1910, ...}

CLI usage with QEA files

All CLI commands accept both XMI and QEA files:

# Build LUR from QEA (10-20x faster than XMI)
lutaml uml build model.qea -o model.lur

# Build LUR from XMI
lutaml uml build model.xmi -o model.lur

# All other commands work the same
lutaml uml search model.lur "Building"
lutaml uml tree model.lur

File validation

require "lutaml/qea/file_detector"

# Check if file is valid QEA
if Lutaml::Qea::FileDetector.qea_file?("model.qea")
  puts "Valid QEA file"
end

# Validate structure
result = Lutaml::Qea::FileDetector.validate_qea("model.qea")
if result[:valid]
  puts "QEA file is valid"
else
  result[:errors].each { |e| puts "ERROR: #{e}" }
end

# Get file information
info = Lutaml::Qea::FileDetector.file_info("model.qea")
puts "Size: #{info[:size_mb]} MB"
puts "Tables: #{info[:table_count]}"
puts "Objects: #{info[:object_count]}"

Performance benchmarking

require "lutaml/qea/benchmark"

# Compare QEA vs XMI parsing
results = Lutaml::Qea::Benchmark.compare("model.qea", "model.xmi")

puts "QEA: #{results[:qea][:time]}s"
puts "XMI: #{results[:xmi][:time]}s"
puts "Speedup: #{results[:speedup]}x faster"

# Display formatted results
puts Lutaml::Qea::Benchmark.format_results(results)

Performance characteristics

Typical performance for a 20MB EA model:

  • QEA parsing: 1-2 seconds

  • XMI parsing: 20-40 seconds

  • Speedup: 10-20x faster

  • Memory: Lower memory footprint with QEA

Configuration

QEA parsing is configured via config/qea_schema.yml:

tables:
  - table_name: t_object
    enabled: true
    model_class: Object

  - table_name: t_attribute
    enabled: true
    model_class: Attribute

  # ... other tables

Limitations

  • QEA files must be SQLite 3 format

  • Requires EA-specific table structure

  • Some EA proprietary features may not be fully supported

  • Only reads from QEA; does not write back to EA database

QEA vs XMI Comparison

LutaML supports both QEA (SQLite) and XMI (XML) formats from Enterprise Architect. While functionally equivalent, QEA parsing offers several advantages:

Performance

  • QEA: 1-2 seconds for 20MB files (direct SQLite access)

  • XMI: 20-40 seconds for same files (XML parsing overhead)

  • Speedup: 10-20x faster parsing with QEA

Data Richness

QEA preserves more semantic information due to direct database access:

Association type differentiation

QEA preserves the distinction between Association, Aggregation, and Composition connector types through the member_end_type field. XMI export from EA hardcodes all association types as "aggregation", losing this semantic information.

Tagged values

QEA includes object properties as tagged values, capturing EA-specific metadata that may not be exported to XMI. For example, a class in QEA might have 3 tagged values while the same class in XMI has 0, representing metadata loss during XMI export.

Association generalization structure

QEA provides rich AssociationGeneralization objects with full type information, while XMI reduces these to simple string IDs, losing structural detail.

Compatibility

  • 99.6% parity between formats for core UML data

  • QEA is the preferred format when working with Enterprise Architect models

  • Both formats produce equivalent Lutaml::Uml::Document structures

LutaML UML Repository (LUR)

General

LutaML UML Repository provides a unified interface for UML models with built-in indexing and package management.

Package format

LUR packages are ZIP archives containing:

model.lur
├── metadata.yaml          # Package info, statistics
├── models/
│   └── document.marshal   # Serialized UML model
├── indexes/
│   ├── all.marshal        # Pre-built indexes
│   └── index_tree.yaml    # Human-readable package tree (NEW)
└── statistics.yaml        # Detailed statistics

The index_tree.yaml file provides a human-readable view of the package hierarchy with class counts, making it easy to inspect the structure without loading the full repository. This is particularly useful for:

  • Quick package structure inspection

  • Debugging package organization

  • Understanding model hierarchy

  • Generating documentation

Quick start

CLI usage

# Build LUR package
lutaml uml package build model.qea -o model.lur
lutaml uml package build model.xmi -o model.lur

# Show package info
lutaml uml package info model.lur

# List packages
lutaml uml list model.lur

# Show package tree
lutaml uml tree model.lur --max-depth 3

# Show class details
lutaml uml show class "MyPackage::MyClass" model.lur

# Search
lutaml uml search "building" model.lur

# Get statistics
lutaml uml stats model.lur

# Command aliases (shortcuts)
lutaml uml ls model.lur           # alias for 'list'
lutaml uml t model.lur            # alias for 'tree'
lutaml uml s class MyClass model.lur  # alias for 'show'
lutaml uml ? "building" model.lur  # alias for 'search'
lutaml uml f --stereotype featureType model.lur  # alias for 'find'

# Interactive shell (REPL)
lutaml uml shell model.lur

Build repository from XMI or QEA

require "lutaml/xmi"

# Build from XMI file
repo = Lutaml::UmlRepository::Repository.from_xmi("model.xmi")

# Build from QEA file
repo = Lutaml::UmlRepository::Repository.from_qea("model.qea")

# Query the model
package = repo.find_package("ModelRoot::MyPackage")
klass = repo.find_class("ModelRoot::MyPackage::MyClass")
classes = repo.find_classes_by_stereotype("featureType")

# Get statistics
stats = repo.statistics
puts "Total classes: #{stats[:total_classes]}"

Save as LUR package

# Export to .lur package (fast loading)
repo.export_to_package("model.lur",
  name: "My Model",
  version: "1.0",
  serialization_format: :marshal  # or :yaml
)

# Load from package (< 100ms vs >5s parsing XMI)
repo = Lutaml::UmlRepository::Repository.from_package("model.lur")

# Smart file detection (auto-detects format)
repo = Lutaml::UmlRepository::Repository.from_file("model.xmi")
repo = Lutaml::UmlRepository::Repository.from_file("model.lur")

# Intelligent caching (uses cache if fresh, rebuilds if stale)
repo = Lutaml::UmlRepository::Repository.from_file_cached("model.xmi")
# Creates model.lur and reuses it on subsequent runs

LUR configuration

General

A configuration file is used to describe package-specific settings for an LUR package, including metadata and features enabled.

The configuration format is as follows:

metadata:
  name: My Model
  version: 1.0
  description: A sample UML model
  license: MIT
  author: John Doe
package:
  input: /path/to/model.xmi  # or .qea
  storage_format: marshal  # or yaml
  include_original_file: true

LUR packages allow full-text search across model elements.

# Get helpful suggestions for typos
repo.find_class("ModelRoot::Buildng", raise_on_error: true)
# => NameError: Class not found: ModelRoot::Buildng
#    Did you mean one of these?
#      - ModelRoot::Building
#      - ModelRoot::BuildingPart

repo.find_package("ModelRoot::i-UP", raise_on_error: true)
# => NameError: Package not found: ModelRoot::i-UP
#    Did you mean one of these?
#      - ModelRoot::i-UR

API reference

Smart loading methods

# Auto-detect file type
repo = Lutaml::UmlRepository::Repository.from_file("model.xmi")
repo = Lutaml::UmlRepository::Repository.from_file("model.lur")

# Smart caching (only rebuilds when XMI is newer than cache)
repo = Lutaml::UmlRepository::Repository.from_file_cached("model.xmi")
repo = Lutaml::UmlRepository::Repository.from_file_cached("model.xmi",
                                                     lur_path: "cache/model.lur")

Error handling with suggestions

# Find class with error handling
klass = repo.find_class("ModelRoot::MyClass", raise_on_error: true)
# Raises NameError with suggestions if not found

# Find package with error handling
package = repo.find_package("ModelRoot::MyPackage", raise_on_error: true)
# Raises NameError with suggestions if not found

Package navigation

# Find package by path
package = repo.find_package("ModelRoot::i-UR::urf")

# List packages
packages = repo.list_packages("ModelRoot::i-UR", recursive: true)

# Get package tree
tree = repo.package_tree("ModelRoot", max_depth: 3)

Class queries

# Find by qualified name
klass = repo.find_class("ModelRoot::i-UR::urf::Building")

# Find by stereotype
feature_types = repo.find_classes_by_stereotype("featureType")

# Get classes in package
classes = repo.classes_in_package("ModelRoot::i-UR::urf", recursive: false)

Inheritance queries

# Get parent class
parent = repo.supertype_of("ModelRoot::MyPackage::ChildClass")

# Get child classes
children = repo.subtypes_of("ModelRoot::MyPackage::ParentClass")

# Get all children recursively
all_children = repo.subtypes_of(parent_class, recursive: true)

# Get inheritance chain
ancestors = repo.ancestors_of("ModelRoot::MyPackage::MyClass")

# Get all descendants
descendants = repo.descendants_of(base_class, max_depth: 2)

Association & diagram queries

# Get associations
assocs = repo.associations_of("ModelRoot::MyPackage::MyClass")

# Get owned associations only
owned = repo.associations_of(my_class, owned_only: true)

# Get diagrams
diagrams = repo.diagrams_in_package("ModelRoot::MyPackage")
diagram = repo.find_diagram("Class Diagram")
all_diagrams = repo.all_diagrams

Search and element display

# Text search
results = repo.search("urban planning", types: [:class, :attribute])
puts "Found #{results[:total]} matches"

# Pattern search
classes = repo.search("^Urban.*Area$", types: [:class])

# Display element details using presenters
presenter = Lutaml::Xmi::Presenters::PresenterFactory.create(klass)
puts presenter.to_text
puts presenter.to_yaml
puts presenter.to_json

Query DSL (Advanced queries)

The Query DSL provides a fluent, expressive interface for building complex queries with method chaining, lazy evaluation, and composable filters.

# Basic query with hash conditions
results = repo.query do |q|
  q.classes.where(stereotype: 'featureType')
end.all

# Complex query with method chaining
results = repo.query do |q|
  q.classes
    .in_package('ModelRoot::i-UR', recursive: true)
    .where { |c| c.attributes&.size.to_i > 10 }
    .order_by(:name, direction: :desc)
    .limit(5)
end.execute

# Immediate execution with query!
results = repo.query! do |q|
  q.classes.with_stereotype('featureType')
end
Query builder methods
  • classes - Start a class query

  • packages - Start a package query

  • where(conditions) - Filter by hash conditions (e.g., stereotype: 'featureType')

  • where { |obj| …​ } - Filter with custom block logic

  • with_stereotype(stereotype) - Shortcut for stereotype filtering

  • in_package(path, recursive: false) - Filter by package membership

  • order_by(field, direction: :asc) - Sort results (:asc or :desc)

  • limit(count) - Limit number of results

  • execute / all - Execute query and return results

  • first - Get first result

  • last - Get last result

  • count - Count matching results

  • any? - Check if any results exist

  • empty? - Check if no results exist

Query examples
# Find all feature types with many attributes
large_features = repo.query! do |q|
  q.classes
    .with_stereotype('featureType')
    .where { |c| c.attributes&.size.to_i > 20 }
    .order_by(:name)
end

# Find classes in package hierarchy
classes = repo.query do |q|
  q.classes
    .in_package('ModelRoot::i-UR', recursive: true)
    .where(is_abstract: false)
end.all

# Complex filtering with regex
results = repo.query! do |q|
  q.classes
    .where(name: /^Building/)
    .where { |c| c.associations&.any? }
    .limit(10)
end

# Combining multiple conditions
feature_types = repo.query do |q|
  q.classes
    .with_stereotype('featureType')
    .where { |c| c.attributes&.size.to_i > 5 }
    .where { |c| c.associations&.size.to_i > 2 }
end

# Get count without loading all results
count = feature_types.count

# Check if any exist
has_results = feature_types.any?

# Get ordered results
sorted = feature_types.order_by(:name, direction: :desc).all
Deferred vs immediate execution
# Deferred execution - build query, execute later
builder = repo.query do |q|
  q.classes.with_stereotype('featureType')
end

# Can add more conditions
builder.where { |c| c.attributes.size > 10 }

# Execute when ready
results = builder.execute

# Immediate execution - execute and return results
results = repo.query! do |q|
  q.classes.with_stereotype('featureType')
end

Statistics & validation

# Get statistics
stats = repo.statistics
puts "Packages: #{stats[:total_packages]}"
puts "Classes: #{stats[:total_classes]}"
puts "Stereotypes: #{stats[:classes_by_stereotype]}"

# Validate model
result = repo.validate
if result.valid?
  puts "Model is valid"
else
  result.errors.each { |error| puts "ERROR: #{error}" }
end

CLI commands

General

The CLI provides 13 commands organized into 5 categories:

Resource lifecycle:

  • build - Build LUR packages from XMI/QEA files

  • info - Show LUR package metadata

  • validate - Validate LUR packages

  • validate-qea - Validate QEA files

Viewing:

  • ls - List elements (packages, classes, diagrams)

  • inspect - Show element details

  • tree - Hierarchical package tree

  • stats - Repository statistics

Querying:

  • search - Full-text search

  • find - Criteria-based search

Output:

  • export - Export to CSV/JSON/Markdown

  • build-spa - Generate SPA documentation site

  • serve - Start interactive web UI

Development:

  • repl - Interactive REPL shell

build - Build LUR package

Build a LUR package from XMI or QEA source files.

lutaml uml build MODEL -o OUTPUT.lur [OPTIONS]

Where,

MODEL

Path to XMI or QEA file

-o, --output

Output LUR file path (default: input with .lur extension)

--name

Package name (optional)

--version

Package version (default: 1.0)

--format

Serialization format: marshal or yaml (default: marshal)

--validate

Validate before building (default: true)

--strict

Fail build on validation errors (default: false)

Example 2. Building from XMI file
$ lutaml uml build model.xmi -o model.lur --name "My Model"

Parses the XMI file, validates the model, and creates a LUR package.

Example 3. Building from QEA file
$ lutaml uml build project.qea -o project.lur --validate

Parses QEA directly, faster than XMI export+parse.

Example 4. Build with strict validation
$ lutaml uml build model.xmi --strict

Fails the build if any validation errors are found.

info - Show package metadata

Display metadata and statistics for a LUR package without loading the full repository.

lutaml uml info LUR [OPTIONS]

Where,

LUR

Path to LUR package file

--format

Output format: text, yaml, or json (default: text)

Example 5. Viewing package information
$ lutaml uml info model.lur

Shows package name, version, creation date, and contents summary.

validate - Validate LUR package

Validate a LUR package for consistency and completeness.

lutaml uml validate LUR [OPTIONS]

Where,

LUR

Path to LUR package file

--verbose

Show detailed per-attribute type resolution information

Checks for:

  • Dangling references

  • Missing types (with detailed resolution paths when --verbose is used)

  • External dependencies

  • Structural integrity

Example 6. Validating a package
$ lutaml uml validate model.lur
Example 7. Verbose validation with detailed type resolution
$ lutaml uml validate model.lur --verbose

Shows detailed information about type resolution for each attribute, helping diagnose type reference issues.

validate-qea - Validate QEA file

Validate QEA file structure, referential integrity, and data quality.

lutaml uml validate-qea FILE [OPTIONS]

Where,

FILE

Path to QEA file

--format

Output format: text or json (default: text)

-o, --output

Save report to file

--strict

Exit with error if validation fails

--show-warnings

Show warnings (default: true)

Example 8. Validating QEA file structure
$ lutaml uml validate-qea model.qea --format json -o report.json

Validates package structure, associations, references, and exports detailed report.

ls - List elements

List elements at the specified path in the repository.

lutaml uml ls LUR [PATH] [OPTIONS]

Where,

LUR

Path to LUR package file

PATH

Package path to list (optional, default: root)

--type

Element type: packages, classes, diagrams, or all (default: packages)

--format

Output format: text, table, yaml, or json (default: text)

-r, --recursive

Include nested elements

--lazy

Use lazy loading for large repositories

Example 9. List top-level packages
$ lutaml uml ls model.lur
Example 10. List classes in a package
$ lutaml uml ls model.lur ModelRoot::Core --type classes
Example 11. List all diagrams
$ lutaml uml ls model.lur --type diagrams

inspect - Show element details

Display detailed information about a specific element.

lutaml uml inspect LUR ELEMENT [OPTIONS]

Where,

LUR

Path to LUR package file

ELEMENT

Element identifier in format type:identifier

Valid types: package, class, diagram, attribute

--format

Output format: text, yaml, or json (default: text)

--include

Sections to include: attributes, associations, operations

Example 12. Inspect a class
$ lutaml uml inspect model.lur class:Building
$ lutaml uml inspect model.lur class:ModelRoot::Core::Building

Shows class details including attributes, associations, and operations.

Example 13. Inspect a package
$ lutaml uml inspect model.lur package:ModelRoot::Core
Example 14. Inspect a diagram
$ lutaml uml inspect model.lur diagram:ClassDiagram1

tree - Show package tree

Display a hierarchical tree view of the package structure.

lutaml uml tree LUR [PATH] [OPTIONS]

Where,

LUR

Path to LUR package file

PATH

Starting package path (optional, default: root)

-d, --depth

Maximum depth to display

--show-counts

Show class and diagram counts (default: true)

--format

Output format: text, yaml, or json (default: text)

Example 15. Show full package tree
$ lutaml uml tree model.lur
Example 16. Show subtree with limited depth
$ lutaml uml tree model.lur ModelRoot::Core --depth 2

show - Display element details

General

The show commands display detailed information about specific UML elements.

Showing class details
lutaml uml show class <QUALIFIED_NAME> --from <LUR_PATH>
Example 17. Viewing a class
$ lutaml uml show class "ModelRoot::CityGML2.0::bldg::Building" --from plateau.lur

Displays:

  • Class name and XMI ID

  • Stereotype and abstract flag

  • Inheritance information

  • Attributes (with types and cardinality)

  • Associations

  • Operations

Showing attribute details
lutaml uml show attribute <QUALIFIED_NAME> --from <LUR_PATH>

Where <QUALIFIED_NAME> includes the class path, e.g., Package::Class::attributeName.

Example 18. Viewing an attribute
$ lutaml uml show attribute "ModelRoot::CityGML2.0::bldg::Building::buildingHeight" --from plateau.lur

Displays:

  • Attribute name

  • Owning class

  • Type and cardinality

  • Visibility and stereotype

  • Documentation

Showing association details
lutaml uml show association <NAME_OR_ID> --from <LUR_PATH>
Example 19. Viewing an association
$ lutaml uml show association "cityObjectMember" --from plateau.lur

Displays:

  • Association name and XMI ID

  • Source and target classes

  • Roles and multiplicities

  • Association type

Showing enumeration details
lutaml uml show enum <QUALIFIED_NAME> --from <LUR_PATH>
Example 20. Viewing an enumeration
$ lutaml uml show enum "ModelRoot::Package::StatusCode" --from plateau.lur

Displays:

  • Enum name and package

  • All literal values

  • Stereotypes

  • Documentation

Showing data type details
lutaml uml show datatype <QUALIFIED_NAME> --from <LUR_PATH>
Example 21. Viewing a data type
$ lutaml uml show datatype "ModelRoot::gml::MeasureType" --from plateau.lur

Displays:

  • Data type name

  • Attributes (if structured)

  • Operations

  • Stereotypes

Output formats

All show commands support multiple output formats via the --format option:

--format text

Formatted text output (default)

--format yaml

YAML structured data

--format json

JSON structured data

Example 22. Exporting element details as JSON
$ lutaml uml show class "ModelRoot::Package::MyClass" --from model.lur --format json

Returns structured JSON data suitable for programmatic processing.

stats - Repository statistics

Display statistics about the repository or a specific package.

lutaml uml stats LUR [OPTIONS]

Where,

LUR

Path to LUR package file

--type

Statistics type: packages, classes, diagrams, or all (default: all)

--detailed

Show detailed breakdown

--format

Output format: text, yaml, or json (default: text)

Example 23. Show repository statistics
$ lutaml uml stats model.lur --detailed

Displays counts of packages, classes, data types, enumerations, diagrams, and stereotypes.

search - Full-text search

The search command performs powerful text and pattern-based search across classes, attributes, and associations with advanced filtering, export capabilities, and intelligent suggestions.

Advanced features include wildcard package matching, regex patterns, field-specific search, result export, and search suggestions.

lutaml uml search <LUR> <QUERY> [OPTIONS]

Where,

<LUR>

Path to LUR package file

<QUERY>

Search query text

--type

Element types to search: class, attribute, association (default: all)

--package

Filter by package path (supports wildcards: *, ?, [abc])

--regex

Treat query as regular expression

--in

Fields to search: name, documentation (default: name)

--format

Output format: text, table, yaml, or json (default: table)

--limit

Maximum results (default: 100)

Example 24. Searching for "building" across all element types
$ lutaml uml search plateau.lur "building"

This searches for "building" in class names, attribute names, and association names, displaying results in a table format:

Search Results for 'building':

Type         | Name                    | Package                              | Details
──────────────────────────────────────────────────────────────────────────────────────
Class        | Building                | ModelRoot::CityGML2.0::bldg          | <<FeatureType>>
Class        | BuildingPart            | ModelRoot::CityGML2.0::bldg          | <<FeatureType>>
Attribute    | buildingHeight          | ModelRoot::CityGML2.0::bldg          | Building::buildingHeight : Double
Attribute    | buildingCoverageRate    | ModelRoot::i-UR::urf                 | Administration::buildingCoverageRate : xs::integer
...

Summary: 28 class(es), 73 attribute(s), 45 association(s)

Core search options:

--element-type <TYPE>

Filter results by element type. Valid values: class, attribute, association.

--package <PATH>

Filter results to show only elements within the specified package path. Supports explicit wildcards: *, ?, [abc].

--sort <FIELD>

Sort results. Valid values: type, name, package. Default: type.

--limit <NUMBER>

Limit the number of results displayed. Default: 100.

--format <FORMAT>

Output format. Valid values: table, text, yaml, json. Default: table.

--regex

Treat query as a regular expression pattern. Enables powerful pattern-based searching.

--in <FIELDS…​>

Specify which fields to search in. Valid values: name, documentation. Default: name. Can specify multiple fields.

--count

Show only result counts without displaying full results. Displays total count and breakdown by element type.

--export <FILE>

Export search results to a file. Format auto-detected from extension (.json or .yaml/.yml).

Example 25. Wildcard package matching
$ lutaml uml search plateau.lur "building" --package "*i-UR*"

Matches any package path containing "i-UR" anywhere. Found 95 results compared to 50 with full path "ModelRoot::Conceptual Models::i-UR".

Wildcard patterns supported:

  • * - Matches any characters

  • ? - Matches single character

  • [abc] - Matches one character from set

Example 26. Regex pattern search
$ lutaml uml search plateau.lur "^Building" --regex --element-type class

Finds all classes whose names start with "Building" (case-sensitive regex). Found 17 classes: Building, BuildingPart, BuildingInstallation, etc.

The --regex flag treats the query as a regular expression:

  • ^Building - Names starting with "Building"

  • .*Address$ - Names ending with "Address"

  • Building|Structure - Names containing either word

Example 27. Searching in documentation
$ lutaml uml search plateau.lur "urban planning" --in name documentation

Searches both name and documentation fields. Useful for finding elements by their purpose or description, not just their name.

Multiple fields can be specified:

  • --in name - Search names only (default)

  • --in documentation - Search documentation only

  • --in name documentation - Search both fields

Example 28. Count-only mode
$ lutaml uml search plateau.lur "building" --count

Shows statistics without displaying full results:

Search Results for 'building':

Total Results: 146

Breakdown by Type:
  Association     45
  Attribute       73
  Class           28

Useful for quick analysis or when combined with filters:

$ lutaml uml search plateau.lur "building" --element-type class --count
Example 29. Exporting search results
$ lutaml uml search plateau.lur "Building" --element-type class --export results.json
$ lutaml uml search plateau.lur "Building" --element-type class --export results.yaml

Exports filtered search results to a file for further processing. The format is auto-detected from the file extension.

Exported data includes:

  • element_type - Type of element (class, attribute, association)

  • qualified_name - Full qualified name

  • package_path - Package location

  • match_field - Which field matched (name or documentation)

  • match_context - Additional context (e.g., class name for attributes)

Example 30. Search suggestions

When no results are found, the search suggests similar terms based on edit distance and substring matching:

$ lutaml uml search plateau.lur "Buiding"
⚠ No results found for 'Buiding'

Did you mean one of these?
  • Building
  • BuildingPart
  • BuildingInstallation

Suggestions use Levenshtein distance algorithm to find close matches.

Example 31. Combining advanced features
$ lutaml uml search plateau.lur "^Build" \
  --regex \
  --package "*CityGML*" \
  --element-type class \
  --sort name \
  --limit 10 \
  --export citygml_buildings.json

This command:

  • Uses regex to find names starting with "Build"

  • Filters to packages containing "CityGML"

  • Shows only classes

  • Sorts by name

  • Limits to 10 results

  • Exports to JSON file

Multiple filters work together seamlessly.

Example 32. Filtering search results by element type
$ lutaml uml search plateau.lur "building" --element-type class

Shows only classes matching "building", excluding attributes and associations.

Example 33. Searching within a specific package
$ lutaml uml search plateau.lur "urban" --package "ModelRoot::Conceptual Models::i-UR"

Searches for "urban" only within the i-UR package and its subpackages.

Pagination

For large result sets, use pagination to view results in manageable chunks.

--per-page <NUMBER>

Number of results per page. Default: 50.

--page <NUMBER>

Page number to display (1-based). Default: 1.

Example 34. Paginating through search results
$ lutaml uml search plateau.lur "class" --per-page 20 --page 1  # First page
$ lutaml uml search plateau.lur "class" --per-page 20 --page 2  # Second page

View results 20 at a time, navigating through pages.

find - Find by criteria

Find elements matching specific criteria.

lutaml uml find LUR [OPTIONS]

Where,

LUR

Path to LUR package file

--stereotype

Filter by stereotype

--package

Filter by package path

--pattern

Match name pattern (regex)

--format

Output format: text, yaml, or json (default: text)

Example 35. Find by stereotype
$ lutaml uml find model.lur --stereotype featureType
Example 36. Find by package
$ lutaml uml find model.lur --package ModelRoot::Core
Example 37. Find by pattern
$ lutaml uml find model.lur --pattern "^Building.*"

build-spa - Generate SPA documentation

A LUR package can be transformed into a Single Page Application (SPA) for interactive browsing of the UML model.

The SPA provides a user-friendly web interface with search, navigation, and detailed class views.

Features of the generated SPA:

  • Vanilla JavaScript: No frameworks required, fast loading

  • Responsive design: Works on desktop and mobile

  • Offline capable: Single-file mode works without a server

  • Search: Full-text search with highlighting

  • Navigation: Package tree with counts, breadcrumbs

  • Detailed view: Comprehensive class information with:

    • Direct attributes and inherited attributes (in separate tables)

    • Direct associations and inherited associations (in separate tables)

    • Operations

    • Inheritance hierarchy (generalizations and specializations)

    • Stereotypes and documentation

Syntax:

lutaml uml build-spa LUR -o OUTPUT [OPTIONS]

Where,

LUR

Path to LUR package file

-o, --output

Output file path (required)

--mode

Generation mode: single_file (default) or multi_file

--title

Documentation title (default: "UML Model Browser")

--theme

Color theme: light (default) or dark

The build-spa command generates an interactive documentation site with:

  • Search functionality: Full-text search across all model elements

  • Package navigation: Tree-based browsing of the package hierarchy

  • Class details: Complete class information including attributes, associations, operations, and inheritance

  • Inherited data: Separate display of inherited attributes and associations

  • Diagram integration: Embedded diagram viewing (when available)

Example 38. Generate single-file SPA (default)
$ lutaml uml build-spa model.lur -o docs/index.html --title "My UML Model"

Creates a single HTML file (3-4MB for large models) with all data, CSS, and JavaScript embedded. Perfect for easy distribution and offline viewing.

Example 39. Generate multi-file SPA
$ lutaml uml build-spa model.lur -o docs/ --mode multi_file

Creates a directory structure with separate HTML, CSS, and JavaScript files. Better for version control and incremental updates.

serve - Start web UI

Start a web server with an interactive UI for browsing the model.

lutaml uml serve LUR [OPTIONS]

Where,

LUR

Path to LUR package file

-p, --port

Port to listen on (default: 3000)

-h, --host

Host to bind to (default: localhost)

Example 40. Start web UI server
$ lutaml uml serve model.lur --port 8080

Starts interactive web interface at http://localhost:8080.

repl - Interactive shell

LutaML provides an interactive command-line shell (REPL) for exploring LUR packages.

Syntax:

lutaml uml repl LUR [OPTIONS]

Where,

LUR

Path to LUR package file

--color

Enable colored output (default: true)

--icons

Enable icons in output (default: true)

Example 41. Start interactive shell
$ lutaml uml repl model.lur

Opens an interactive shell with commands like cd, ls, tree, find, search, bookmarks, and more.

The interactive shell provides a full-featured command-line interface for exploring UML repositories:

# Start interactive shell
lutaml uml shell model.lur

# Inside the shell:
lutaml[/]> help                    # Show available commands
lutaml[/]> ls                      # List packages in current location
lutaml[/]> cd i-UR::urf            # Navigate to package
lutaml[/i-UR::urf]> pwd            # Show current path
lutaml[/i-UR::urf]> tree           # Show tree from current location
lutaml[/i-UR::urf]> find Building  # Find classes
lutaml[/i-UR::urf]> show 1         # Show first search result
lutaml[/i-UR::urf]> bookmark add urf  # Bookmark current location
lutaml[/i-UR::urf]> bm urf         # Jump to bookmark
lutaml[/i-UR::urf]> stats          # Show statistics
lutaml[/i-UR::urf]> exit           # Exit shell

The shell provides a number of useful features:

  • Tab completion for commands and paths

  • Command history persisted to ~/.lutaml-xmi-history

  • Colorized output with Unicode icons

  • Contextual prompts showing current location

  • Error handling with helpful messages

    Navigation commands
    cd PATH

    Change to package path

    pwd

    Print current working path

    ls [PATH]

    List packages at path

    tree [PATH]

    Show tree from path

    up

    Go to parent package

    root

    Go to ModelRoot

    back

    Go to previous location

    Query commands
    find CLASS_NAME

    Find class (fuzzy search)

    show class QNAME

    Show class details

    show package PATH

    Show package details

    show NUMBER

    Show numbered result from last search

    search QUERY

    Full-text search

    ? QUERY

    Alias for search

    Bookmark commands
    bookmark add NAME

    Bookmark current path or last result

    bookmark list

    List all bookmarks

    bookmark go NAME

    Jump to bookmark

    bookmark rm NAME

    Remove bookmark

    bm NAME

    Quick jump to bookmark

    Utility commands
    results

    Show last search results

    export last csv FILE

    Export last results to CSV

    export last json FILE

    Export to JSON

    export last yaml FILE

    Export to YAML

    help [COMMAND]

    Show help

    history

    Show command history

    clear

    Clear screen

    config

    Show configuration

    stats

    Quick statistics

    exit, quit, q

    Exit shell

Examples

See the examples/ directory for complete examples:

  • examples/lur_basic_usage.rb - Basic repository operations

  • examples/lur_cli_workflow.rb - Command-line workflow

  • examples/lur_statistics.rb - Statistics and validation

Copyright Ribose. BSD-3 License.