Skip to content

Developer Knowledge Base

A.J. Stein edited this page Apr 20, 2023 · 34 revisions

This page is a collection of assorted tasks and topics developers from the NIST OSCAL Team will need or want as part of development activities. Documentation items, when specifically relevant to OSCAL, could and should make their way into official documentation with commits to the git repository's Markdown files. For official documentation, bug reports for error corrections and feature request issues identify and track work items. Changes to information here are not tracked that way. See the note on the bottom of this page. Information this page and children pages are for supporting activities underlying OSCAL development: code snippets for testing data format snippets (JSON, XML, YAML), software configuration, and common queries in different querying languages (JMESPath for JSON, XPath for XML, etc.).

NIST Dev Lunch and Learn Archive

Software

OxygenXML

Useful Plugins

  • Java Classes Generator
  • JSON Schema Documentation Generator
  • OpenAPI Tester
  • Oxygen Emmet Plugin
  • Oxygen Emmet Plugin
  • XSD to JSON Schema converter
  • XSpec Framework
  • XSpec Helper Viewer

Scenario Transformation Setup

This is an opinionated view, but Oxygen has a variety of configuration options for setting up a scenario for applying one or more XSLT transformations against a source document, a scenario for executing a XProc pipeline, and many more.

Below is how some of us use Editor Variables and other configuration elements. As a rule, some of us will use a variable for the source document and hard-code the path to the transform or XProc pipeline when running the scenarios interactively.

Code

Java-based Tooling

How do I invoke Java dependencies directly from a pom.xml file?

In several places across our stack we make use of Java-based tooling such as Saxon and Calabash. The version of these tools can be pinned using POM files, such as the one present in the build/ directory. Below is a simple template script that can be used to invoke a Java dependency directly from a POM file.

#!/usr/bin/env bash

# Fail early if an error occurs
set -Eeuo pipefail

if ! [ -x "$(command -v mvn)" ]; then
  echo 'Error: Maven (mvn) is not in the PATH, is it installed?' >&2
  exit 1
fi

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
OSCAL_DIR="${SCRIPT_DIR}/../../../.." # Edit this to resolve to the OSCAL root from the script's directory
POM_FILE="${OSCAL_DIR}/build/pom.xml"
# Grab any additional files relative to the root OSCAL directory (like stylesheets)

MAIN_CLASS="net.sf.saxon.Transform" #edit this to target your application's main class. below are a few examples:
# XML Calabash: "com.xmlcalabash.drivers.Main"
# Saxon: "net.sf.saxon.Transform"

# Perform any argument processing here, such as preselecting stylesheets in Saxon, etc.
# Note here "${*// /\\ }" is a shell expansion that escapes spaces within arguments.
# For more information, see https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
ARGS=${*// /\\ }

mvn \
    -f "$POM_FILE" \
    exec:java \
    -Dexec.mainClass="$MAIN_CLASS" \
    -Dexec.args="$ARGS"

Note that this template is often extended to parse arguments directly. See an example of this in the profile resolution Saxon wrapper.

This approach has several key advantages:

  1. The script can refer to resources invariably to the user's current working directory, making it more portable.
  2. The user does not have to worry about downloading, copying, or otherwise managing any of the Java dependencies.
  3. A lot of the complexity of consuming stylesheets and other operations can be hidden from the user, making our stack more approachable.

XPath

How do I check for multiple kinds of elements at the same time with XPath 3.0?

Let's say we want to look for the following OSCAL syntax elements in XML at the same time:

  • any definition of a field with the name "with-id" in one or more target documents
  • any definition of a flag with the name "pattern" in one or more target documents
  • any definition of an assembly with the name "matching" in one or more target documents

Apply the following query against the target document(s) (for this example any Metaschema definition in src/metaschema/*.xml), observing use of the | ("union") operator:

//(
    define-flag[@name='pattern']
   | define-assembly[@name='matching']
   | define-field[@name='with-id']
 )

Here is a sneakier way to do something similar:

//@name[.=('pattern','matching','with-id')]/parent::*

parent::* can also be shortened to .. for those who prefer.

Mathematically, this path returns a superset of the nodes returned by the first path given, although in a particular metaschema they are likely to be the same.

This takes advantage of a feature of general comparison operators in XPath (=, <, >, <=, >=) namely that they support comparing sequences, i.e. many values on either side of the operand, hence .=('a','b','c').

Troubleshooting

GitHub Actions

Why do workflows on some runners return HTTP status code 0, failing builds or opening issues?

lychee or markdown-link-check will run an automated scan of the destination of almost every link (there is an exclude list) for every Markdown file in the repo and in the generated HTML that runs the website. Infrequently, GitHub's websites and external websites as well will rate-limit the runner's attempt open the link target or there is an internal failure on the runner. The resulting HTTP status is 0 (and that is not a normal one in the 200, 400, or 500 range). The build failure will indicate the link or an issue will be automatically opened that looks like the report below.

FILE: build/ci-cd/README.md

[✖] https://nodejs.org/en/

[✓] https://github.com/jessedc/ajv-cli

2 links checked.

If you can open the full URL reliably in your web browser on a developer workstation, you can safely presume this is a the infrequent hiccup on a GitHub Actions runner and close the issue as a false positive.

Clone this wiki locally