{"id":47802525,"url":"https://github.com/adunning/xml-model-validator","last_synced_at":"2026-04-22T02:04:26.638Z","repository":{"id":345514724,"uuid":"1185310209","full_name":"adunning/xml-model-validator","owner":"adunning","description":"Validate XML from xml-model processing instructions using Relax NG (RNG/RNC) and Schematron","archived":false,"fork":false,"pushed_at":"2026-03-29T19:55:02.000Z","size":123,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-29T21:32:54.106Z","etag":null,"topics":["docbook","jing-trang","relaxng","saxon","schematron-validation","schxslt","tei","tei-xml","xml","xml-schema","xml-validation"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adunning.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-18T13:02:08.000Z","updated_at":"2026-03-29T19:55:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/adunning/xml-model-validator","commit_stats":null,"previous_names":["adunning/xml-model-validator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/adunning/xml-model-validator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adunning%2Fxml-model-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adunning%2Fxml-model-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adunning%2Fxml-model-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adunning%2Fxml-model-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adunning","download_url":"https://codeload.github.com/adunning/xml-model-validator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adunning%2Fxml-model-validator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31364989,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T15:19:21.178Z","status":"ssl_error","status_checked_at":"2026-04-03T15:19:20.670Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docbook","jing-trang","relaxng","saxon","schematron-validation","schxslt","tei","tei-xml","xml","xml-schema","xml-validation"],"created_at":"2026-04-03T17:11:17.034Z","updated_at":"2026-04-22T02:04:26.628Z","avatar_url":"https://github.com/adunning.png","language":"Java","readme":"# XML Model Validator\n\nValidate XML from `xml-model` processing instructions with a GitHub Action and\nCLI built for Relax NG and Schematron-heavy workflows such as TEI, DocBook,\nJATS, and other complex XML repositories.\n\nIt is designed to feel native in GitHub:\n\n- inline annotations on failing files\n- a readable step summary for every run\n- structured outputs for later workflow steps\n- an optional JSON report for artifacts or downstream automation\n\nThis repository provides:\n\n- a Java CLI\n- a self-contained GitHub Action ready for GitHub Marketplace\n\nRelease artifacts are published on GitHub Releases as:\n\n- `xml-model-validator.jar`\n- `xml-model-validator.jar.sha256`\n\nThe validator:\n\n- parses `xml-model` processing instructions with a proper XML parser\n- validates Relax NG schemas with Jing\n- validates Schematron with Saxon and SchXslt2\n- supports Relax NG and Schematron `xml-model` declarations in the same file\n- supports Relax NG XML syntax (`.rng`) and RELAX NG Compact Syntax (`.rnc`)\n- supports standalone Schematron files and embedded Schematron inside Relax NG schemas, including `.rnc` via conversion to `.rng`\n- supports Schematron `phase` selection from the `xml-model` processing instruction\n- recognizes common schema hints from `schematypens`, `type`, and schema file extensions\n- follows remote schema URLs and caches downloaded schemas in the workspace\n- supports repository configuration from a single TOML file for schema aliases\n  and rule-based `xml-model` handling\n- supports optional rule-based `xml-model` configuration by directory and/or\n  file extension, including fallback and full inline replacement modes\n- resolves XML paths, caches, and optional aliases against the consuming\n  repository when run as a GitHub Action\n- can emit machine-readable JSON reports for automation\n- emits GitHub annotations for validation failures and warnings\n- writes GitHub step summaries for Action runs, including skipped changed-file checks\n\nIt is a good fit for repositories that keep validation rules in `xml-model`\nprocessing instructions and want pull-request feedback directly in GitHub,\nincluding scholarly editing, technical publishing, journal/article XML, and\nother custom XML workflows.\n\n## GitHub Action\n\nWhat the Action gives you in GitHub:\n\n- inline workflow annotations for validation errors and warnings\n- a Markdown step summary with counts, run context, and issue details\n- structured outputs for later workflow steps\n- an optional saved JSON report for artifacts or downstream automation\n\nTypical workflow:\n\n1. check out the repository\n2. run the Action against the whole repository, one directory, explicit files, or changed files only\n3. inspect annotations and the step summary in GitHub\n4. optionally use the structured outputs or saved JSON report in later steps\n\n### Minimal usage\n\n```yaml\n- uses: actions/checkout@v6\n- uses: adunning/xml-model-validator@v2\n```\n\nThe default run validates all matching files in the repository and reports the\nresult through annotations and the job summary.\n\n### Recommended workflows for most repositories\n\nSave one of these workflows as `.github/workflows/validate-xml.yml`. If your default branch is not\n`main`, replace that value with your repository's default branch name.\n\n#### Validate all XML files on pull requests and pushes\n\nThis is a simple configuration suitable for repositories with a small number of XML files (in the hundreds rather than thousands) or those that want to validate everything on every run.\n\n```yaml\nname: Validate XML\n\non:\n  push:\n    paths:\n      - \"**/*.xml\"\n  pull_request:\n    paths:\n      - \"**/*.xml\"\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\njobs:\n  validate-xml:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Validate XML\n        uses: adunning/xml-model-validator@v2\n```\n\n#### Validate changed XML on pull requests and pushes, with a weekly full check\n\nIn a larger and frequently changing repository, a workflow that validates only modified XML files reduces validation time for pull requests and pushes. In the example below, a scheduled run validates the full repository once a week to catch any drift.\n\nIf your default branch is not `main`, replace that value with your repository's default branch name.\n\n```yaml\nname: Validate XML\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"**/*.xml\"\n  pull_request:\n    paths:\n      - \"**/*.xml\"\n  schedule:\n    - cron: \"0 3 * * 1\"\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\njobs:\n  validate-xml:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Validate changed XML\n        if: github.event_name != 'schedule' \u0026\u0026 github.event_name != 'workflow_dispatch'\n        uses: adunning/xml-model-validator@v2\n        with:\n          changed_files_only: true\n\n      - name: Validate full XML set\n        if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'\n        uses: adunning/xml-model-validator@v2\n```\n\nIf validation also depends on schema or config files, expand the `paths` filter\nor remove it so schema-only changes also trigger validation.\n\n### Advanced usage\n\nVersion tag semantics:\n\n- `@v2` is a floating major tag that tracks the latest `2.x.y` release.\n- `@v2.2.1` is an immutable exact release tag.\n- This repository publishes releases from `vX.Y.Z` tags and then updates the\n  matching major tag (`vX`) automatically.\n\nValidate a directory recursively:\n\n```yaml\n- uses: adunning/xml-model-validator@v2\n  with:\n    directory: collections\n```\n\nValidate XML files stored with a non-`.xml` extension:\n\n```yaml\n- uses: adunning/xml-model-validator@v2\n  with:\n    directory: styles\n    file_extensions: csl\n```\n\nUse changed-file mode in pull requests and upload a JSON report:\n\n```yaml\n- uses: actions/checkout@v6\n\n- id: xml-validate\n  uses: adunning/xml-model-validator@v2\n  with:\n    changed_files_only: true\n    json_report_path: reports/xml-validation.json\n\n- uses: actions/upload-artifact@v4\n  if: always() \u0026\u0026 steps.xml-validate.outputs.json_report_path != ''\n  with:\n    name: xml-validation-report\n    path: ${{ steps.xml-validate.outputs.json_report_path }}\n```\n\nFor repositories that mostly care about pull-request validation, `changed_files_only: true`\nplus a saved JSON report is usually the best starting point. For repositories\nthat want a full repository check on every run, the default Action invocation is\nusually enough.\n\nIf you want both fast review feedback and a periodic full-repository safety\ncheck, use the recommended workflow above and switch between\n`changed_files_only: true` and a default full run based on `github.event_name`.\n\n## Common patterns\n\nMost users will probably want to use only the GitHub Action inputs. Use a\nrepository config file when you need more than one rule, want stable\nrepository-wide configuration, or want different schema sets for different\ndirectories.\n\nApply a fallback remote Relax NG schema to files in one directory with only\nAction inputs:\n\n```yaml\n- uses: adunning/xml-model-validator@v2\n  with:\n    xml_model_rule_mode: fallback\n    xml_model_rule_directory: styles\n    xml_model_rule_extension: csl\n    xml_model_declarations: |\n      href=\"https://example.org/schema/styles.rng\" schematypens=\"http://relaxng.org/ns/structure/1.0\"\n      href=\"https://example.org/schema/styles.sch\" schematypens=\"http://purl.oclc.org/dsdl/schematron\"\n```\n\nBecause `file_extensions` is omitted here, the Action discovers both `.xml`\nfiles and `.csl` files in `styles`. Set `file_extensions: csl` as well if you\nwant to restrict discovery to `.csl` only.\n\nReplace inline declarations for one directory with remote Relax NG and\nSchematron rules with only Action inputs:\n\n```yaml\n- uses: adunning/xml-model-validator@v2\n  with:\n    xml_model_rule_mode: replace\n    xml_model_rule_directory: tei\n    xml_model_rule_extension: xml\n    xml_model_declarations: |\n      href=\"https://example.org/schema/tei.rng\" schematypens=\"http://relaxng.org/ns/structure/1.0\"\n      href=\"https://example.org/schema/tei.sch\" schematypens=\"http://purl.oclc.org/dsdl/schematron\"\n```\n\nUse a repository config file when you need multiple rules or want to pin a\nremote schema URL to a local file:\n\n```toml\n[schema_aliases]\n\"https://example.org/schema/styles.rng\" = \"schemas/styles.rng\"\n\n[[xml_model_rules]]\ndirectory = \"styles\"\nextension = \"csl\"\nmode = \"fallback\"\n\n[[xml_model_rules.declarations]]\nhref = \"https://example.org/schema/styles.rng\"\nschematypens = \"http://relaxng.org/ns/structure/1.0\"\n\n[[xml_model_rules]]\ndirectory = \"tei\"\nextension = \"xml\"\nmode = \"replace\"\n\n[[xml_model_rules.declarations]]\nhref = \"https://example.org/schema/tei.rng\"\nschematypens = \"http://relaxng.org/ns/structure/1.0\"\n\n[[xml_model_rules.declarations]]\nhref = \"https://example.org/schema/tei.sch\"\nschematypens = \"http://purl.oclc.org/dsdl/schematron\"\n```\n\nValidate only the XML files changed by the current push or pull request:\n\n```yaml\n- uses: adunning/xml-model-validator@v2\n  with:\n    changed_files_only: true\n```\n\nChoose how changed files are discovered:\n\n```yaml\n- uses: adunning/xml-model-validator@v2\n  with:\n    changed_files_only: true\n    changed_source: auto # auto | api | git\n```\n\nValidate explicit files and stop on the first failure:\n\n```yaml\n- uses: adunning/xml-model-validator@v2\n  with:\n    files: |\n      docs/a.xml\n      docs/b.xml\n    fail_fast: true\n```\n\n## Inputs\n\n- `files`: newline-delimited list of files to validate explicitly\n- `files_from`: newline-delimited file list path\n- `directory`: directory to scan recursively\n- `file_extensions`: comma- or whitespace-separated file extensions to discover when scanning directories or changed files; a leading period is optional and the default is `.xml`\n- `changed_files_only`: validate only files with matching extensions changed by the current push or pull request\n- `changed_source`: source for `changed_files_only` file discovery (`auto`, `api`, `git`)\n- `jobs`: number of workers, `0` means automatic\n- `config`: optional TOML validator config file containing schema aliases and\n  `xml-model` rules\n- `xml_model_rule_mode`: optional inline `xml-model` rule mode (`fallback` or\n  `replace`)\n- `xml_model_rule_directory`: optional directory scope for the inline\n  `xml-model` rule; when no selection input is set, this also becomes the\n  default directory to validate\n- `xml_model_rule_extension`: optional file extension scope for the inline\n  `xml-model` rule; a leading period is optional, and when `file_extensions` is\n  omitted the Action still discovers `.xml` files by default and adds this\n  value to the discovery set\n- `xml_model_declarations`: optional newline-delimited declarations for one\n  inline `xml-model` rule; remote schema URLs are supported and are expected to\n  be the most common case\n- `fail_fast`: stop after the first failing file\n- `check_schematron_schema`: run SchXslt assembled-schema checks before validating documents that use Schematron; disabled by default\n- `schematron_severity_threshold`: skip Schematron assertions with a severity lower than the threshold; one of `INFO`, `WARNING`, `ERROR`, `FATAL`; defaults to `INFO` (report all assertions)\n- `json_report_path`: optional path, relative to the repository root or absolute, where the Action should save a JSON validation report\n\nIf you do not provide `files`, `files_from`, `directory`, or `changed_files_only`,\nthe action validates all matching files in the repository by default.\n\nIf `xml_model_rule_directory` is set and no selection input is provided, the\nAction validates that directory by default.\n\nThe Action accepts at most one selection input at a time. If you provide more\nthan one of `files`, `files_from`, `directory`, or `changed_files_only`, the run\nfails with an input error.\n\nWhen `changed_files_only: true`:\n\n- `changed_source: auto` (default) tries the GitHub API for pull request and\n  push events, then falls back to git diff if API discovery is unavailable.\n- `changed_source: api` requires GitHub event context and API access.\n- `changed_source: git` uses local git diff logic.\n- If no changed files with matching extensions are found, the action reports that validation was\n  skipped, emits a GitHub notice and step summary, and exits successfully.\n\nDuring GitHub Action runs, the default output format emits both workflow\nannotations and a Markdown step summary. The summary includes counts, duration,\nrun context, and issue details when validation runs, and an explicit skip\nmessage when `changed_files_only` finds nothing to validate.\n\nThe Action also exposes structured outputs you can use in later workflow steps:\n\n- `skipped`\n- `files_checked`\n- `failed_files`\n- `warning_count`\n- `json_report_path`\n\n## Outputs\n\n- `skipped`: `true` when `changed_files_only` found no matching files and the Action exited successfully without validating\n- `files_checked`: number of files actually validated\n- `failed_files`: number of files that failed validation\n- `warning_count`: number of warning-level issues reported\n- `json_report_path`: absolute path to the saved JSON report when `json_report_path` is set; otherwise empty\n\nExample:\n\n```yaml\n- id: xml-validate\n  uses: adunning/xml-model-validator@v2\n  with:\n    changed_files_only: true\n    json_report_path: reports/xml-validation.json\n\n- name: Show validation result\n  if: always()\n  run: |\n    echo \"Skipped: ${{ steps.xml-validate.outputs.skipped }}\"\n    echo \"Checked: ${{ steps.xml-validate.outputs.files_checked }}\"\n    echo \"Failed: ${{ steps.xml-validate.outputs.failed_files }}\"\n    echo \"Warnings: ${{ steps.xml-validate.outputs.warning_count }}\"\n    echo \"JSON report: ${{ steps.xml-validate.outputs.json_report_path }}\"\n```\n\nUpload the saved JSON report as a workflow artifact:\n\n```yaml\n- id: xml-validate\n  uses: adunning/xml-model-validator@v2\n  with:\n    directory: collections\n    json_report_path: reports/xml-validation.json\n\n- uses: actions/upload-artifact@v4\n  if: always() \u0026\u0026 steps.xml-validate.outputs.json_report_path != ''\n  with:\n    name: xml-validation-report\n    path: ${{ steps.xml-validate.outputs.json_report_path }}\n```\n\n## Configuration Reference\n\nFor repositories that need local schema aliases or rule-based `xml-model`\nbehaviour, provide `.xml-validator/config.toml`. Use `--config` or the\n`config` Action input to override that location.\n\nExample:\n\n```toml\n[schema_aliases]\n\"https://example.com/schema.rng\" = \"schemas/local.rng\"\n\n[[xml_model_rules]]\ndirectory = \"styles\"\nextension = \"csl\"\nmode = \"fallback\"\n\n[[xml_model_rules.declarations]]\nhref = \"https://example.org/schema/styles.rng\"\nschematypens = \"http://relaxng.org/ns/structure/1.0\"\n\n[[xml_model_rules]]\ndirectory = \"tei\"\nextension = \"xml\"\nmode = \"replace\"\n\n[[xml_model_rules.declarations]]\nhref = \"schemas/tei.rng\"\nschematypens = \"http://relaxng.org/ns/structure/1.0\"\n\n[[xml_model_rules.declarations]]\nhref = \"schemas/tei.sch\"\nschematypens = \"http://purl.oclc.org/dsdl/schematron\"\n```\n\n`schema_aliases` maps remote schema URLs to local files relative to the config\nfile.\n\n`xml_model_rules` lets you define different schema sets for different\ndirectories or extensions. Rule `directory` values are resolved relative to the\nrepository root. Rule `extension` values may be written with or without a\nleading period. Declaration `href` values may be remote `http://` or `https://`\nURLs, repository-root-relative local paths, or absolute local paths. Local\ndeclaration `href` values in config and Action-supplied rules are resolved from\nthe repository root.\n\nEach rule can match by directory and/or extension, and can either:\n\n- `fallback`: apply only when the file has no inline `xml-model` declarations\n- `replace`: ignore inline `xml-model` declarations and use the configured\n  declarations instead\n\nWhen multiple rules match a file, the most specific directory rule wins; an\nextension-qualified rule beats the same directory without an extension. If two\nrules match with the same specificity and precedence, validation fails with an\nambiguity error instead of choosing one implicitly. Inline `xml-model`\nprocessing instructions inside the XML file still follow standard XML relative\nresolution against the XML file itself.\n\nThe GitHub Action’s inline override inputs define only one rule per run. Use\nthe TOML config file when you need multiple directory-specific or\nextension-specific rules in the same workflow.\n\nWhen an inline rule provides `xml_model_rule_extension` and `file_extensions`\nis omitted, the effective discovery set is `.xml` plus the inline rule\nextension. Set `file_extensions` explicitly when you want to narrow discovery\nto a smaller set such as only `.csl`.\n\nConfigured remote schema URLs use the same download and cache behaviour as\nremote schema URLs referenced from inline `xml-model` processing instructions.\n\nEach declaration supports the same fields the validator reads from inline\n`xml-model` instructions:\n\n- `href` (required)\n- `schematypens` (optional)\n- `type` (optional)\n- `phase` (optional)\n\nThe config schema is strict: unsupported keys are rejected so configuration\nmistakes fail clearly instead of being ignored silently.\n\n## Supported schema forms\n\nThe action is intentionally focused on the schema types most commonly used with\n`xml-model` in editorial workflows:\n\n- Relax NG XML syntax\n- RELAX NG Compact Syntax\n- standalone Schematron\n- embedded Schematron in Relax NG XML syntax schemas\n- embedded Schematron in RELAX NG Compact Syntax schemas via conversion to XML syntax\n\nEmbedded Schematron extraction follows Relax NG `include` and `externalRef`\nlinks for local and remote schemas. Relative references in remote `.rnc`\nschemas are resolved against the original remote URL before conversion.\n\nIt does not currently attempt to validate every schema language that `xml-model`\ncan theoretically reference.\n\n## Runtime model\n\nThe GitHub Action sets up Java internally and runs the validator with\n`java -jar`.\n\nOn a cold runner, the composite action first attempts to download\n`xml-model-validator.jar` from the GitHub Release that matches the action ref\n(for example, `@v2` or `@v2.2.1`). If the release asset is not available, it\nfalls back to building the runnable jar from source.\n\nThe built jar is cached under `~/.cache/xml-model-validator/jar`, and its cache\nkey is derived from the runner OS and action ref.\n\nWhen a jar cache miss triggers a source build, the action runs\n`gradle/actions/setup-gradle`, which restores and saves Gradle User Home state\n(`~/.gradle`) using its default cache strategy.\n\nRemote schema downloads and prepared Schematron artifacts are cached under\n`~/.cache/xml-model-validator/schema-downloads` and\n`~/.cache/xml-model-validator/schematron`. The action restores the latest\nruntime cache and saves a fresh one at the end of each run so those artifacts\ncan accumulate safely over time.\n\nThe `changed_files_only` mode expects the repository to be available in the runner,\nwhich normally means using `actions/checkout@v6` earlier in the job.\n\n## Local development\n\nBuild the runnable jar:\n\n```bash\n./gradlew -q jar -x test\n```\n\n## CLI\n\nThe CLI requires exactly one input source per invocation:\n\n- `--directory PATH` to scan a directory recursively\n- `--files-from PATH` to read a newline-delimited file list from a file\n- `--files-from -` to read a newline-delimited file list from standard input\n- `FILES...` to validate explicit file paths\n\nThe CLI rejects invocations that omit an input source or combine more than one\ninput source.\n\n`--files-from` expects one path per line. Blank lines are ignored. When you use\n`--files-from -`, paths are read from standard input, which makes the CLI work\nwell in pipelines such as `find ... | xml-model-validator --files-from -`.\n\nFile discovery rules:\n\n- `--directory` and `--files-from` apply `--file-extensions`\n- if `--file-extensions` is omitted, discovery defaults to `.xml`\n- if an inline rule sets `--rule-extension` and `--file-extensions` is omitted,\n  discovery uses both `.xml` and that rule extension\n- explicit `FILES...` arguments are validated as given and are not filtered by\n  `--file-extensions`\n\nOutput formats:\n\n- `--format text` writes human-readable diagnostics\n- `--format github` writes GitHub workflow annotations and summaries\n- `--format json` writes a machine-readable report to standard output\n- if `--format` is omitted, the CLI defaults to `text` locally and `github`\n  inside GitHub Actions\n\nSchematron options:\n\n- `--check-schematron-schema` enables SchXslt assembled-schema checks before\n  validating documents that use Schematron; disabled by default\n- `--schematron-severity-threshold LEVEL` skips Schematron assertions with a\n  severity lower than the threshold; one of `INFO`, `WARNING`, `ERROR`, `FATAL`;\n  defaults to `INFO` (report all assertions)\n\nInspection mode:\n\n- `--plan` prints the resolved input source, config path, extensions, rules,\n  and file set without running validation\n- `--plan` succeeds even when the resolved file set is empty, so it can be used\n  to debug discovery\n\nExit status:\n\n- `0` means validation succeeded\n- `1` means one or more files failed validation\n- `2` means command-line usage was invalid\n\nOutput behaviour:\n\n- by default, successful runs are quiet\n- validation warnings and errors are written to standard error\n- use `--verbose` to print progress information and successful summaries\n\nRun:\n\n```bash\njava -jar build/libs/xml-model-validator.jar --directory path/to/xml -j 0\njava -jar build/libs/xml-model-validator.jar --plan --directory path/to/xml\njava -jar build/libs/xml-model-validator.jar --verbose --directory path/to/xml -j 0\nfind path/to/xml -name '*.xml' -print | java -jar build/libs/xml-model-validator.jar --files-from - -j 0\njava -jar build/libs/xml-model-validator.jar --files-from path/to/files.txt -j 0\njava -jar build/libs/xml-model-validator.jar path/to/a.xml path/to/b.xml -j 0\njava -jar build/libs/xml-model-validator.jar --directory path/to/styles --file-extensions csl -j 0\njava -jar build/libs/xml-model-validator.jar --directory path/to/styles --file-extensions csl --config .xml-validator/config.toml -j 0\n```\n\nShow CLI usage:\n\n```bash\njava -jar build/libs/xml-model-validator.jar --help\n```\n\nShow CLI version:\n\n```bash\njava -jar build/libs/xml-model-validator.jar --version\n```\n\nWrite a JSON report:\n\n```bash\njava -jar build/libs/xml-model-validator.jar --format json path/to/a.xml path/to/b.xml\n```\n\nPreview the full validation plan:\n\n```bash\njava -jar build/libs/xml-model-validator.jar --plan --format json --directory path/to/xml\n```\n\nVerify a published release artifact:\n\n```bash\nVERSION=v2.2.1 # replace with the release tag you want to verify\ncurl -LO \"https://github.com/adunning/xml-model-validator/releases/download/${VERSION}/xml-model-validator.jar\"\ncurl -LO \"https://github.com/adunning/xml-model-validator/releases/download/${VERSION}/xml-model-validator.jar.sha256\"\nshasum -a 256 -c xml-model-validator.jar.sha256\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadunning%2Fxml-model-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadunning%2Fxml-model-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadunning%2Fxml-model-validator/lists"}