Working with Metaschema
This guide explains how to use the oscal-cli for Metaschema-related operations.
The oscal-cli includes Metaschema functionality inherited from metaschema-cli, including:
- Evaluating Metapath expressions against OSCAL documents
- Understanding OSCAL's Metaschema-defined structure
- Working with Metaschema constraint validation
Metapath is an XPath-like expression language designed for querying Metaschema-based documents. Unlike XPath, which is XML-specific, Metapath works identically regardless of whether your document is in XML, JSON, or YAML format.
oscal-cli metapath eval -e "//control" catalog.json
oscal-cli metapath eval -e "//control/title" --to=json catalog.json
The following examples demonstrate frequently used queries for OSCAL documents. These patterns form the foundation for more complex queries:
oscal-cli metapath eval -e "//control" catalog.json
oscal-cli metapath eval -e "//control[starts-with(@id, 'ac-')]" catalog.json
oscal-cli metapath eval -e "//control/title" catalog.json
oscal-cli metapath eval -e "//control[prop[@name='label']]" catalog.json
oscal-cli metapath eval -e "count(//control)" catalog.json
oscal-cli metapath eval -e "//param" catalog.json
If you're familiar with XPath, Metapath syntax will feel natural. The following tables provide a quick reference for common patterns:
Path expressions navigate the document structure. The // operator is particularly useful for finding elements at any depth:
| Expression | Description |
|---|---|
/catalog |
Root catalog element |
//control |
All controls at any depth |
control/part |
Parts within controls |
.. |
Parent element |
. |
Current element |
Predicates filter results based on conditions. They appear in square brackets after the element selector:
| Expression | Description |
|---|---|
control[@id='ac-1'] |
Control with specific ID |
control[1] |
First control |
control[last()] |
Last control |
control[position() < 5] |
First four controls |
Built-in functions perform calculations and string operations. They can be used in predicates or as the expression itself:
| Function | Description |
|---|---|
count(//control) |
Count controls |
string-length(title) |
Length of title |
starts-with(@id, 'ac') |
ID starts with ‘ac’ |
contains(title, 'Access') |
Title contains ‘Access’ |
These functions are specific to OSCAL and are registered by the OSCAL CLI:
| Function | Description |
|---|---|
has-oscal-namespace(prop, 'https://fedramp.gov/ns/oscal') |
Check property namespace |
resolve-profile(import) |
Resolve profile import |
Docker lets you run Metapath queries without installing Java. Mount your local directory to access your OSCAL documents:
# Evaluate Metapath query
docker run --rm -v "$(pwd):/data" \
ghcr.io/metaschema-framework/oscal-cli:latest \
metapath eval -e "//control" /data/catalog.json
# Query with formatted output
docker run --rm -v "$(pwd):/data" \
ghcr.io/metaschema-framework/oscal-cli:latest \
metapath eval -e "//control/title" --to=json /data/catalog.json
The following examples show real-world query patterns you might use when working with OSCAL catalogs. These combine the path expressions, predicates, and functions covered above:
oscal-cli metapath eval -e "//control/@id" catalog.json
oscal-cli metapath eval -e "//control[contains(@id, '.')]" catalog.json
oscal-cli metapath eval -e "//control[prop[@name='status'][@value='withdrawn']]" catalog.json
oscal-cli metapath eval -e "//control[@id='ac-1']/part[@name='statement']" catalog.json
oscal-cli metapath eval -e "//control[.//insert[@type='param'][@id-ref='ac-1_prm_1']]" catalog.json
Behind the scenes, OSCAL documents are defined by Metaschema module specifications. Understanding this foundation helps you write better queries and interpret validation errors. Metaschema specifies:
- Model structure - Assemblies, fields, flags that define the document hierarchy
- Data types - UUID, date-time, markup-line, and other value constraints
- Constraints - Required fields, cardinality limits, and validation patterns
The OSCAL specification is divided into modules, each defining a specific document type:
| Module | Content |
|---|---|
oscal_catalog |
Catalogs, groups, controls |
oscal_profile |
Profiles and imports |
oscal_ssp |
System Security Plans |
oscal_component-definition |
Component definitions |
oscal_assessment-plan |
Assessment plans |
oscal_assessment-results |
Assessment results |
oscal_poam |
Plans of Action and Milestones |
Metapath queries can extract data for use in CI/CD workflows—generating reports, validating control counts, or creating derived artifacts:
- name: List control IDs
run: |
oscal-cli metapath eval -e "//control/@id" catalog.json > control-ids.txt
- name: Count controls
run: |
count=$(oscal-cli metapath eval -e "count(//control)" catalog.json)
echo "Catalog contains $count controls"
Common issues when working with Metapath expressions and their solutions:
Error: Invalid Metapath expression
Fix: Check expression syntax. Use single quotes around string literals:
oscal-cli metapath eval -e "//control[@id='ac-1']" catalog.json
If the query returns nothing:
- Verify the document structure
- Check element names and paths
- Try a broader query first:
//control
Continue learning about the OSCAL CLI with these related guides:
- Validating OSCAL - Validate with constraints
- CLI Reference - Complete command reference
- Metapath Reference - Full Metapath specification

