README
Source: README.md

Saxon-Forms

Saxon-Forms is an XForms implementation written using Interactive XSLT 3.0. Interactive XSLT 3.0 is a feature of Saxon-JS, which is an XSLT 3.0 run-time written in pure JavaScript for use in the browser or a platform that supports JavaScript.

See conference papers below:

Implementing XForms using interactive XSLT 3.0. XML Prague 2018.

Distributing XSLT Processing between Client and Server. XML London 2017.

Quickstart (5 minutes)

For first-time contributor onboarding, run:

npm run setup
npm run doctor
npm run verify:setup

Prerequisites

Saxon-JS can be downloaded at Saxon-JS (older versions available at the archive).

1) Bootstrap environment

npm run setup

2) Build Saxon-Forms SEF

npm run build:sef

This generates sef/saxon-xforms.sef.json and syncs it into test-app/sef/saxon-xforms.sef.json.

3) Run examples locally

npm run examples

Then open http://127.0.0.1:5174/ and start with:

npm run examples starts a local server and continues running until you stop it manually.

4) Run end-to-end tests (Playwright)

npm run test:e2e

Run with a specific browser mode:

npm run test:e2e:chrome
npm run test:e2e:firefox
npm run test:e2e:both

Or pass the harness flag directly:

npm run test:e2e -- --browser=firefox

To run tests interactively:

npm run test:e2e:ui

Common commands

NIST Playwright engine index

tests/xsd/nist/nist-facets-engine.spec.ts reads precomputed case data from:

Generate/update this file with:

npm run build:nist-engine-index

Use a custom index path for experimentation by setting NIST_ENGINE_CASE_INDEX to an absolute or repo-relative JSON path.

Troubleshooting

Contributing

See CONTRIBUTING.md for development workflow, validation expectations, and PR standards. For complete machine/bootstrap setup (including external datasets and tools), see SETUP.md.

Support expectations

Saxon-Forms support maturity is tracked by conformance behavior and implementation coverage.

For current details:

If you are evaluating feature readiness for production, use those files as the source of truth.

Documentation workflow (DocBook + ant4docbook)

The repository now includes a DocBook-based implementation guide under docs/docbook/, with chapter-level checkpoints and standalone UML/BPMN references.

Prerequisite for DocBook builds:

Generated DocBook outputs are written to builds/docs-docbook/.

GitHub Pages documentation site (CI/CD)

The repository supports an assembled static docs site artifact under builds/site/. This includes:

Build and validate locally:

The CI workflow .github/workflows/pages-docs.yml builds and validates this artifact on pull requests, and deploys to GitHub Pages on pushes to the default branch.

Note on examples in static hosting:

Cryptographic Functions (Optional)

The XForms digest() and hmac() functions require the @noble/hashes library (MIT license). These functions are optional — forms that do not use digest() or hmac() work without it. When the library is not loaded, these functions return an empty string instead of crashing.

Quick setup

  1. Install the dependency:

    npm install @noble/hashes
    
  2. Build the crypto bundle:

    node scripts/build-crypto.mjs
    

    This produces builds/saxon-forms-crypto.js (~14 KB, 6 KB gzipped).

  3. Load the bundle before Saxon-Forms in your HTML:

    <script src="saxon-forms-crypto.js"></script>
    <!-- then load SaxonJS and your XForm as usual -->
    

CDN alternative

If you prefer not to install locally, you can load the pre-built bundle from your own CDN or copy builds/saxon-forms-crypto.js alongside your other assets.

What happens without it

If the crypto bundle is not loaded, digest() and hmac() return empty strings. Forms that use these functions will render normally but any conditional logic that depends on hash values (e.g. ref="self::node()[digest(...) = '...']") will not match.

Technical Details