From 0010340e9fc3968ace73dc6edc7237b2bb5ffba2 Mon Sep 17 00:00:00 2001 From: Wendell Piez Date: Fri, 16 Feb 2024 11:37:00 -0500 Subject: [PATCH] Metaschema XSLT Inspector draft release in progress (#73) (#98) * Metaschema XSLT Inspector (#73) Several months of work building InspectorXSLT using test-driven-development. Also includes considerable work on XSpec support including XProc and Saxon runtimes, scripts and CI/CD support. --------- Co-authored-by: A.J. Stein * Update XSPEC-BATCH.xsl On-the-fly modification of JUnit XML results * Adjustments to XSpec reporting under CI (#99) * Fine adjustments in prep for 'nearly good enough' XSpec support under ci/cd (in feature branch) * Adjustments for legibility * Another touchup * Buffs in view of CI/CD and local/CL use cases for testing under make including new error-on-fail option * Added to script documentation * Still polishing help msg * Now with some more nicer XProc and scripting supporting ongoing maintenance / dev * adjustments to test runtime * Further refinements to testing & scripts * Rationalizing including file name regularization * Further configuration enhancements * More help in docs * Further testing/tuning/tweaking test runtimes and docs * Further alignment * New 'quiet' XSpec batching script, plus adjustment * New 'make' feature for testing InspectorXSLT * More Makefile edits / cleanup * Further docs and readme improvements * Removed obsolete Schematron implementation, no longer of interest * More polishing * Further small but useful improvements and cleanup * Added another utility script * Continuing to touch up * Add permissions for EnricoMi/publish-unit-test-result-action Using the guidance from the action's instructions: https://github.com/EnricoMi/publish-unit-test-result-action?tab=readme-ov-file#support-fork-repositories-and-dependabot-branches * Add artifact event pull for EnricoMi/publish-unit-test-result-action Using the guidance from the action's instructions: https://github.com/EnricoMi/publish-unit-test-result-action?tab=readme-ov-file#support-fork-repositories-and-dependabot-branches * Ensure XSpec test results comment always made on PR * [WIP] Dedupe event trigger and inline JUnit XML processing in CI workflow --------- Co-authored-by: A.J. Stein --------- Co-authored-by: A.J. Stein --- .github/workflows/publish.yml | 39 + .github/workflows/test.yml | 55 + .gitignore | 4 +- README.md | 4 + TESTING.md | 54 +- src/Makefile | 7 +- src/schema-gen/InspectorXSLT/Makefile | 64 + src/schema-gen/InspectorXSLT/TESTING.md | 135 + .../generator/generate-inspector-xslt.xsl | 996 +++++++ .../generator/generator-boilerplate.xsl | 550 ++++ .../generator/oscal-inspector-fixup.xsl | 57 + .../inspector-generator-checkup.sch | 22 + src/schema-gen/InspectorXSLT/mx-grabber.xsl | 35 + src/schema-gen/InspectorXSLT/mx-reporter.xsl | 67 + src/schema-gen/InspectorXSLT/planning.md | 101 + src/schema-gen/InspectorXSLT/readme.md | 405 +++ .../InspectorXSLT/report-validation-html.xsl | 94 + .../InspectorXSLT/testing/.gitignore | 5 + .../testing/COMPUTER-INSPECTOR-PRODUCE.xpl | 38 + .../testing/CURRENT-TEST-MODELS-REFRESH.xpl | 77 + .../testing/INSPECTOR-XSLT-TEST.xpl | 60 + .../testing/TEST-INSPECTOR-RUNTIME.xpl | 91 + .../testing/computer-invalid/invalid1.xml | 12 + .../testing/computer-invalid/invalid10.xml | 35 + .../testing/computer-invalid/invalid2.xml | 33 + .../testing/computer-invalid/invalid3.xml | 67 + .../testing/computer-invalid/invalid4.xml | 69 + .../testing/computer-invalid/invalid5.xml | 69 + .../testing/computer-invalid/invalid6.xml | 68 + .../testing/computer-invalid/invalid7.xml | 70 + .../testing/computer-invalid/invalid8.xml | 70 + .../testing/computer-invalid/invalid9.xml | 40 + .../testing/computer-testing.sch | 26 + .../testing/computer-valid/valid1.xml | 60 + .../testing/computer-valid/valid2.xml | 26 + .../testing/computer-valid/valid3.xml | 56 + .../testing/computer-valid/valid4.xml | 46 + .../testing/computer_metaschema.xml | 369 +++ .../current/computer_metaschema-inspector.xsl | 2361 +++++++++++++++++ .../current/computer_metaschema-schema.xsd | 952 +++++++ .../current/tiny_metaschema-inspector.xsl | 889 +++++++ .../current/tiny_metaschema-schema.xsd | 377 +++ .../InspectorXSLT/testing/inspect-computer.sh | 79 + .../InspectorXSLT/testing/planning.md | 53 + .../InspectorXSLT/testing/readme.md | 35 + .../refresh-computer-inspector-saxon.sh | 53 + .../testing/refresh-computer-inspector.sh | 35 + .../testing/refresh-inspector-anyway.sh | 63 + .../testing/refresh-test-inspectors.sh | 33 + .../testing/smoketest-computer-inspector.sh | 32 + .../computer-constraints.xspec | 474 ++++ .../computer-modeling.xspec | 330 +++ .../tiny-markupdatatypes.xspec | 73 + .../validations-in-batch.xspec | 88 + .../xspec-patterns.xspec | 182 ++ .../boilerplate-testing.xsl | 69 + .../inspector-generation-xspec/copy_me.xsl | 9 + .../datatype-testing.xspec | 155 ++ .../inspector-production-functions.xspec | 66 + .../produce-inspector.xspec | 66 + .../test-inpector-boilerplate.xspec | 77 + .../xspec-smoketest.xspec | 50 + .../InspectorXSLT/testing/tiny_metaschema.xml | 104 + .../testing/tinydata/bigbadtiny.xml | 21 + .../InspectorXSLT/testing/tinydata/tiny1.xml | 22 + src/schema-gen/METASCHEMA-INSPECTOR-XSLT.xpl | 129 + src/schema-gen/METASCHEMA-METATRON-wip.xpl | 59 - src/schema-gen/METASCHEMA-XSD-TEST.xpl | 4 +- src/schema-gen/METASCHEMA-XSD.xpl | 42 + .../Schematron/make-metaschema-metatron.xsl | 629 ----- .../metatron-datatype-functions.xsl | 107 - src/schema-gen/TESTING.md | 19 + src/schema-gen/mvn-inspectorXSLT-xsl.sh | 52 + ...> nist-metaschema-MAKE-INSPECTOR-XSLT.xsl} | 8 +- src/schema-gen/readme.md | 13 +- src/testing/make_common.mk | 2 +- src/testing/xspec-assurance.sch | 18 + src/util/no-op.xsl | 12 + .../oxygen-refactoring-xspec-renumber.xml | 9 + src/util/xslt-smoketest.xsl | 106 + src/util/xspec-fixup.sch | 43 + src/util/xspec-renumber.xsl | 36 + support/xspec-dev/XSPEC-BATCH.xsl | 164 +- .../xspec-dev/mvn-saxon-xspec-batch-quiet.sh | 80 + support/xspec-dev/mvn-saxon-xspec-batch.sh | 28 +- support/xspec-dev/mvn-saxon-xspec-html.sh | 0 support/xspec-dev/mvn-xproc-xspec-html.sh | 0 support/xspec-dev/readme.md | 1 + support/xspec-dev/xspec-summary-reduce.xsl | 16 +- 89 files changed, 11521 insertions(+), 880 deletions(-) create mode 100644 .github/workflows/publish.yml create mode 100644 .github/workflows/test.yml create mode 100644 src/schema-gen/InspectorXSLT/Makefile create mode 100644 src/schema-gen/InspectorXSLT/TESTING.md create mode 100644 src/schema-gen/InspectorXSLT/generator/generate-inspector-xslt.xsl create mode 100644 src/schema-gen/InspectorXSLT/generator/generator-boilerplate.xsl create mode 100644 src/schema-gen/InspectorXSLT/generator/oscal-inspector-fixup.xsl create mode 100644 src/schema-gen/InspectorXSLT/inspector-generator-checkup.sch create mode 100644 src/schema-gen/InspectorXSLT/mx-grabber.xsl create mode 100644 src/schema-gen/InspectorXSLT/mx-reporter.xsl create mode 100644 src/schema-gen/InspectorXSLT/planning.md create mode 100644 src/schema-gen/InspectorXSLT/readme.md create mode 100644 src/schema-gen/InspectorXSLT/report-validation-html.xsl create mode 100644 src/schema-gen/InspectorXSLT/testing/.gitignore create mode 100644 src/schema-gen/InspectorXSLT/testing/COMPUTER-INSPECTOR-PRODUCE.xpl create mode 100644 src/schema-gen/InspectorXSLT/testing/CURRENT-TEST-MODELS-REFRESH.xpl create mode 100644 src/schema-gen/InspectorXSLT/testing/INSPECTOR-XSLT-TEST.xpl create mode 100644 src/schema-gen/InspectorXSLT/testing/TEST-INSPECTOR-RUNTIME.xpl create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid1.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid10.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid2.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid3.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid4.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid5.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid6.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid7.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid8.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid9.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-testing.sch create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-valid/valid1.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-valid/valid2.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-valid/valid3.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer-valid/valid4.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/computer_metaschema.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/current/computer_metaschema-inspector.xsl create mode 100644 src/schema-gen/InspectorXSLT/testing/current/computer_metaschema-schema.xsd create mode 100644 src/schema-gen/InspectorXSLT/testing/current/tiny_metaschema-inspector.xsl create mode 100644 src/schema-gen/InspectorXSLT/testing/current/tiny_metaschema-schema.xsd create mode 100644 src/schema-gen/InspectorXSLT/testing/inspect-computer.sh create mode 100644 src/schema-gen/InspectorXSLT/testing/planning.md create mode 100644 src/schema-gen/InspectorXSLT/testing/readme.md create mode 100644 src/schema-gen/InspectorXSLT/testing/refresh-computer-inspector-saxon.sh create mode 100644 src/schema-gen/InspectorXSLT/testing/refresh-computer-inspector.sh create mode 100644 src/schema-gen/InspectorXSLT/testing/refresh-inspector-anyway.sh create mode 100644 src/schema-gen/InspectorXSLT/testing/refresh-test-inspectors.sh create mode 100644 src/schema-gen/InspectorXSLT/testing/smoketest-computer-inspector.sh create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/computer-constraints.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/computer-modeling.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/tiny-markupdatatypes.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/validations-in-batch.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/xspec-patterns.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/boilerplate-testing.xsl create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/copy_me.xsl create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/datatype-testing.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/inspector-production-functions.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/produce-inspector.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/test-inpector-boilerplate.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/xspec-smoketest.xspec create mode 100644 src/schema-gen/InspectorXSLT/testing/tiny_metaschema.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/tinydata/bigbadtiny.xml create mode 100644 src/schema-gen/InspectorXSLT/testing/tinydata/tiny1.xml create mode 100644 src/schema-gen/METASCHEMA-INSPECTOR-XSLT.xpl delete mode 100644 src/schema-gen/METASCHEMA-METATRON-wip.xpl create mode 100644 src/schema-gen/METASCHEMA-XSD.xpl delete mode 100644 src/schema-gen/Schematron/make-metaschema-metatron.xsl delete mode 100644 src/schema-gen/Schematron/metatron-datatype-functions.xsl create mode 100644 src/schema-gen/mvn-inspectorXSLT-xsl.sh rename src/schema-gen/{nist-metaschema-MAKE-XML-METATRON.xsl => nist-metaschema-MAKE-INSPECTOR-XSLT.xsl} (85%) create mode 100644 src/testing/xspec-assurance.sch create mode 100644 src/util/no-op.xsl create mode 100644 src/util/oxygen-refactoring-xspec-renumber.xml create mode 100644 src/util/xslt-smoketest.xsl create mode 100644 src/util/xspec-fixup.sch create mode 100644 src/util/xspec-renumber.xsl create mode 100644 support/xspec-dev/mvn-saxon-xspec-batch-quiet.sh mode change 100644 => 100755 support/xspec-dev/mvn-saxon-xspec-batch.sh mode change 100644 => 100755 support/xspec-dev/mvn-saxon-xspec-html.sh mode change 100644 => 100755 support/xspec-dev/mvn-xproc-xspec-html.sh diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..6c2a5984 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,39 @@ +# Rationale and instructions for this GitHub Actions workflow: +# https://github.com/EnricoMi/publish-unit-test-result-action?tab=readme-ov-file#support-fork-repositories-and-dependabot-branches + +name: Publish Test Results +on: + workflow_run: + workflows: ["CI"] + types: + - completed +permissions: {} +jobs: + test-results: + name: Test Results + runs-on: ubuntu-latest + if: github.event.workflow_run.conclusion != 'skipped' + permissions: + checks: write + pull-requests: write + actions: read + steps: + - name: Download and Extract Artifacts + uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 + with: + run_id: ${{ github.event.workflow_run.id }} + path: artifacts + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@8885e273a4343cd7b48eaa72428dea0c3067ea98 + with: + commit: ${{ github.event.workflow_run.head_sha }} + action_fail: true + fail_on: "test failures" + event_file: artifacts/Test Results Event/event.json + event_name: ${{ github.event.workflow_run.event }} + github_token: ${{ secrets.GITHUB_TOKEN }} + check_name: XSpec Test Results + comment_mode: always + files: "**/*_junit-report.xml" + report_individual_runs: true + deduplicate_classes_by_file_name: false diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..ac6e0ee9 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,55 @@ +name: CI +on: + push: + branches: + - main + - develop + pull_request: {} +permissions: + checks: write + pull-requests: write +env: + JAVA_VERSION: "17" + JAVA_DISTRIBUTION: "temurin" +jobs: + test: + name: "Test and Collect Results" + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + - uses: actions/setup-java@v3 + with: + distribution: "${{ env.JAVA_DISTRIBUTION }}" + java-version: "${{ env.JAVA_VERSION }}" + - name: Run unit tests + run: | + make -C src unit-test + id: unit-tests + - name: Run integration tests + run: | + make -C src smoke-test + id: integration-tests + - name: Run specification tests + run: | + make -C src spec-test + id: spec-tests + - name: Upload test results + if: always() + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + with: + name: Test Results + path: | + **/*_junit-report.xml + event_file: + name: "Upload Results to Event File" + runs-on: ubuntu-20.04 + needs: test + steps: + - name: Upload + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + with: + name: Test Results Event + path: ${{ github.event_path }} diff --git a/.gitignore b/.gitignore index 74d8585b..3cc589cb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ *.xpr # other generated files -xspec/*-result.html +**/*-xspec/*-result.html +**/xspec/*-result.html +**/*xspec*-result.html # test outputs src/**/test_output/ diff --git a/README.md b/README.md index a6be09a1..d8129dd6 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,10 @@ See the [Metaschema Repository](https://github.com/usnistgov/metaschema) and its See the Project [Wiki](https://github.com/usnistgov/metaschema-xslt/wiki) for documentation maintained on this site. +## Acknowledgements + +This work and especially work on testing XSLT represented by this project would have been impossible without examples and leadership provided by persons including AG; AJS; DW; NW. + ## Required outline This page includes all the following, as described by guidelines at https://raw.githubusercontent.com/usnistgov/opensource-repo/main/README.md diff --git a/TESTING.md b/TESTING.md index a0f4e7e4..2b2f7b0a 100644 --- a/TESTING.md +++ b/TESTING.md @@ -16,29 +16,36 @@ If code legibility and consistency become an issue, we can consider more stringe ## *Test Everything* -TBD - a TEST EVERYTHING subroutine. +With `make`, `bash`, and Maven installed, `make test -C src` runs all the tests (tested under Ubuntu) in the `src` directory relative to the current working directory. -## Testing technologies +The top-level Makefile in this directory collects commands from Makefiles distributed throughout the repo. + +You can also use `make` in isolation from the top-level testing, to focus on your application. As a developer you only need to worry about the folder containing your application, binding test tasks to the targets 'smoke-test', 'spec-test' and 'unit-test' as need be. + +Model such a Makefile, which calls XSpec for testing XSLT, after the example `src/schema-gen/InspectorXSLT/Makefile`. + +Experiment using different Makefile targets as configured in the various directories. + +For any directory, `make` with no arguments should offer tips. + +### Testing technologies [XSpec](https://github.com/xspec/xspec/) is the preferred testing harness for XSLT in this initiative. XSpec test suites can be either self-contained, or can reference testing artifacts maintained externally. The repository contains XSpec examples demonstrating a range of usage patterns that can be applied. Script-driven testing should rely on the same dependencies as the runtimes they test, as documented. -## Global functional testing - -`src/testing` includes resources for global-level testing. This folder or its contents should not to be moved or edited without fully testing *all* test runtimes, as resources inside this directory are sometimes dependencies. +### Extensions to XSpec -Do not commit anything to this folder that you do not wish to stay there indefinitely; instead, copy into a sibling (temporary) directory that can be deleted freely. +Currently we are emulating and re-engineering some specific XSpec capabilities in the [support/xspec-dev](support/xspec-dev) folder. -## Application component-level (functional) unit testing +These efforts are focused on producing and refining XSpec runtimes for various use cases and scenarios with specialized requirements faced by this project, such as arbitrary batching and iXML support. Tools we develop here are released under the same terms as Metaschema-XSLT (as open-source software). -`src/**/testing` includes (functional) testing for utilities supported in a given folder. -When developing applications, feel free to add and modify any `testing` folder or its contents within the scope of work. +## Test-driven development -Unit tests are expected to run successfully when committed - both completing, and passing all applicable tests. Keep in mind that most testing frameworks support marking tests as not applicable (in XSpec, [flag a scenario or `expect` as `pending`](https://github.com/xspec/xspec/wiki/Focusing-Your-Efforts#marking-scenario-or-expectation-as-pending)), so it is possible to write tests ahead of an implementation and still pass. +Almost all testing in this repository falls into the category of either XSLT transformations, or runtimes that embed transformations. -### Test-driven development +### The approach While this project began as an experimental proof of concept, it now aims for higher levels of assurance and confidence than are necessary or appropriate for applications intended only to produce findings regarding feasibility and levels of effort. Accordingly, our development approach has shifted from rapid prototyping to a more explicit and traceable process of design, specification and implementation. @@ -46,17 +53,28 @@ If you touch a particular unit of code that doesn't have tests, write tests for This expenditure of effort prevents bugs (easier than repairing them) and guards against regression, opening opportunities to do more interesting things. So it is not so much "extra" as an investment in future stability and sustainability. -## Test applications +The approach can require changing some habits. Looking for inspiration and "striking while the iron is hot" no longer works as well (since the forge must be warmed up first). Sometimes immediate gratification has to be set aside. Yet the payoffs are substantial, and come early. -`examples` (tbd) includes top-level independent metaschema examples made for testing and demonstration. +## Global functional testing -This location is available for lightweight and toy applications, useful for evaluation, demonstration and learning. Fully built-out applications of Metaschema can also call this repository in as a submodule (like [OSCAL](https://github.com/usnistgov/oscal)). +`src/testing` includes resources for global-level testing. This folder or its contents should not to be moved or edited without fully testing *all* test runtimes, as resources inside this directory are sometimes dependencies. + +Do not commit anything to this folder that you do not wish to stay there indefinitely; instead, copy into a sibling (temporary) directory that can be deleted freely. + +## Application component-level (functional) unit testing + +`src/**/testing` includes (functional) testing for utilities supported in a given folder. + +When developing applications, feel free to add and modify any `testing` folder or its contents within the scope of work. + +Unit tests are expected to run successfully when committed - both completing, and passing all applicable tests. Keep in mind that most testing frameworks support marking tests as not applicable (in XSpec, [flag a scenario or `expect` as `pending`](https://github.com/xspec/xspec/wiki/Focusing-Your-Efforts#marking-scenario-or-expectation-as-pending)), so it is possible to write tests ahead of an implementation and still pass. ## Testing under CI/CD -Also tbd +Github Actions is configured in the file [.github/workflows/test.yml](.github/workflows/test.yml) + +Note that since this logic enters the `Makefile` logic from the top, make executes the specified subroutines recursively. + +Accordingly, adding a test subroutine to a `spec-tests` Makefile configuration anywhere in the repository has the effect of enabling it (turning it on) for CI/CD as well. -Links of interest: -- https://github.com/nkutsche/xspec-maven-plugin -- https://github.com/galtm/xslt-accumulator-tools/blob/db1c6b2a/pom.xml#L68 diff --git a/src/Makefile b/src/Makefile index 5c46f596..71cdcad9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,10 @@ include testing/make_common.mk -# Each subdirectory that has a makefile -dirs:=$(dir $(wildcard ./*/Makefile)) +# Each subdirectory (recursively) that has a makefile +# Makefile wildcard function does not support that, so we use the shell +# function with the find utility and look ever Makefile in a child dir +# relative to this one, but exclude this one to use with the FOREACH macro. +dirs:=$(shell find '.' ! -wholename ./Makefile -name 'Makefile' -printf "%h\n") .PHONY: test test: ## Run all tests diff --git a/src/schema-gen/InspectorXSLT/Makefile b/src/schema-gen/InspectorXSLT/Makefile new file mode 100644 index 00000000..5a9e87bb --- /dev/null +++ b/src/schema-gen/InspectorXSLT/Makefile @@ -0,0 +1,64 @@ +include ../../testing/make_common.mk + +# INCLUDES: +# unit-test - unit testing - XSLT production templates for InspectorXSLT +# smoke-test - smoke testing - whether an XSLT is produced and compiles in a run +# spec-test - specification conformance testing - functional runtime tests of the generated XSLT +# refresh-testing - update InspectorXSLT and XSD for test metaschemas +# xspec - run XSpec tests in designated folder +# clean - clean up designated output folder + +module_path:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) +output_folder:=$(module_path)/test_output +xspec_script=$(realpath $(module_path)/../../../support/xspec-dev/mvn-saxon-xspec-batch-quiet.sh) +xspec_ci_script=$(realpath $(module_path)/../../../support/xspec-dev/mvn-saxon-xspec-batch.sh) +smoketest_script=$(realpath $(module_path)/testing/smoketest-computer-inspector.sh) +testing-refresh_script=$(realpath $(module_path)/testing/refresh-test-inspectors.sh) +folder=. + +.PHONY: test +test: smoke-test unit-test spec-test ## Run all tests + + +.PHONY: spec-test +spec-test: ## Run all specification tests + LOGFILE="$(output_folder)/inspector-functional-tests.log" $(xspec_ci_script) \ + "folder=$(module_path)/testing/tests/inspector-functional-xspec" \ + "report-to=$(output_folder)/inspector-functional-tests_report.html" \ + "junit-to=$(output_folder)/inspector-functional-tests_junit-report.xml" \ + "stop-on-error=yes" \ + "recurse=yes" + +.PHONY: unit-test +unit-test: ## Run all unit tests + LOGFILE="$(output_folder)/inspector-generation-tests.log" $(xspec_ci_script) \ + "folder=$(module_path)/testing/tests/inspector-generation-xspec" \ + "report-to=$(output_folder)/inspector-generation_report.html" \ + "junit-to=$(output_folder)/inspector-generation_junit-report.xml" \ + "stop-on-error=yes" \ + "recurse=yes" + + +.PHONY: smoke-test +smoke-test: ## Run InspectorXSLT production smoke test + $(smoketest_script) + + +.PHONY: refresh-testing +refresh-testing: ## Update InspectorXSLT and XSD for test metaschemas (doesn't run tests) + $(testing-refresh_script) + + +.PHONY: xspec +xspec: ## Run all *.xspec in a designated folder, quietly - use folder=[folder] + LOGFILE="$(output_folder)/$(folder)-xspec-tests.log" $(xspec_script) \ + "baseURI=file:$(module_path)/" \ + "folder=$(folder)" \ + "report-to=$(output_folder)/inspector-$(folder)-tests_report.html" \ + "stop-on-error=no" \ + "recurse=yes" + + +.PHONY: clean +clean: ## Remove test output + rm -fr $(output_folder)/* \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/TESTING.md b/src/schema-gen/InspectorXSLT/TESTING.md new file mode 100644 index 00000000..15a12810 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/TESTING.md @@ -0,0 +1,135 @@ +# Testing the XSLT Metaschema Inspector + +Produced from a metaschema, an Inspector is an XSLT transformation which produces, when applied to an XML document, error and warning messages from that document respecting its conformance to the rules dictated by that metaschema. + +In other words the Inspector is a Schema Emulator, as it aims to return (or expose) effectively the same information as schema validation. + +Broadly, this presents at least three areas for testing (each of which has complexities) + +- Generation of the Inspector XSLT from controlled (metaschema) sources +- Functionality of the Inspector XSLT +- Interfaces and outputs / runtime options for Inspector XSLT + +Currently we focus on the *first two* of these, producing functional results in a simplified format that we can build to later - testing interface targets at that time as appropriate. An example would be producing HTML or Markdown reports: for now we test only generic reports in a format we control. + +Find resources for testing the XSLT Inspector and its production in the [testing](testing) subdirectory. + + +## Testing under `make` + +Documented in the Makefile - + +For example + +``` +> make test +``` + +Runs all tests using provided scripting. + +Don't commit unless this passes. + +``` +> make smoke-test +``` + +Runs only the 'smoke tests' (end to end production pipeline testing - are viable artifacts produced irrespective of their functionality or correctness) + +Available: + - `smoke-test` - builds an XSLT from the `computer_metaschema.xml` test example, and attempts to execute the resulting XSLT over stub input. A failure indicates a problem in the production pipeline - it is either broken or wrong + - `spec-test` - runs specification tests - does the produced XSLT behave as expected when used on the possible range of (XML) inputs? this is a validator: does it validate? + - `unit-test` - runs transformation template- and function-level unit tests regulating the mapping between source (Metaschema) and target (XSLT) expressions. + +Note this is work in progress and may change over time especially as we bring more tests in. + +## Model metaschemas for testing + +### `current` resource cache + +The testing/current directory contains copies of resources produced by the Inspector generator and related tools for testing, including: + +- Current-best Inspector implementation for any metaschemas, as generated +- Current-best XSD expressing (a subset of) the same rules as the corresponding Inspector, for a metaschema module, for testing +- Current-best 'composed' metaschema instance for each testing metaschema. i.e. a fully assembled and linked metaschema module, useful for debugging + +Within these artifacts, initial comments should give information regarding date of creation. + +### "Computer Model" metaschema + +This suite uses an extended variant of the 'computer metaschema' model by AJ Stein and team for testing, maintained here as [testing/computer_metaschema.xml](testing/computer_metaschema.xml). + +The Inspector XSLT feature set can be tested by generating XSLT and schemas and creating instances (e.g. `valid` and `invalid` instances) from this metaschema, which exercise its feature set. + +See the original in [the specification's repository](https://github.com/usnistgov/metaschema/blob/develop/examples/). + +#### Refresh the 'computer model' XSD + +Use a script such as [../mvn-xsd-schema-xsl.sh](../mvn-xsd-schema-xsl.sh) or the XSLT [../nist-metaschema-MAKE-XSD.xsl](../nist-metaschema-MAKE-XSD.xsl) to produce an XSD file for the [testing/computer_metaschema.xml](testing/computer_metaschema.xml). + +This XSD should validate the same set of rules as the Inspector (excluding Metaschema query constraints) and can be used to cross check functionality. Note that this XSD is also dynamically generated and might itself have bugs or issues. (If only in principle. In reality, the schema generators are also tested both in the lab and the field.) Irrespective of this question, the requirements are that both processes (schema validation and Inspector-XSLT validation) are effectively congruent, compatible and "the same" inasmuch as they detect all the same problems in data. + +A copy of the current-best schema is also here, to be refreshed as necessary): [testing/current/computer_metaschema-xmlschema.xsd](testing/current/computer_metaschema-xmlschema.xsd) + +### Refresh the 'computer model' Inspector XSLT + +Before testing the Computer Inspector XSLT, the copy kept for testing must be refreshed. + +First, build `current/computer_inspector.xsl` from `computer_metaschema.xml` using `generate-inspector-xslt` + + - Use ../METASCHEMA-INSPECTOR-XSLT.xpl runtime or script to provide metaschema composition, then apply the 'generator' stylesheet to produce the Inspector XSLT + - The top-level ../nist-metaschema-MAKE-INSPECTOR-XSLT.xsl applies the same XSLT pipeline + - Either test metaschema, or any correctly tagged metaschema, can be refreshed this way + +### Tiny Data mini-model + +An additional small metaschema is provided specifically for the purpose of isolating markup-based datatypes (`markup-line` and `markup-multiline`) in their various configurations and testing the correctness of validations of this markup (passing valid markup and reporting invalid markup). + +Use it and test with it the same way as the Computer metaschema. + +"Tiny data" supports term bases (controlled vocabularies) and documents using controlled terminology, using a very few tags. With a little creative extension-by-restriction it can be used for glossaries and arbitrary structured prose in a lightweight XML format supportive of further improvement, enhancement, and conversion. + +## Testing the Inspector XSLT + +Question: *Is the XSLT produced from a metaschema instance capable of addressing its functional requirements?* + +To address this question, functional requirements can be isolated and illustrated both in standalone complete documents, and in document fragments maintained as XSpec test suites. + +### Standalone document-level tests + +Question: *Can test samples including nominally-valid and invalid test cases be known to be valid or invalid, as described?* + +Within `testing`, `computers-valid` contains Computer Model instances expected to test as valid. + +Examples within `computers-invalid` when tested by the Computer MOdel Inspector (or any validator) are expected to return appropriate warnings and errors. They may be commented with notes indicating their lapses. + +For testing the InspectorXSLT transformation, the XSpec file [testing/validations-in-batch.xspec](testing/validations-in-batch.xspec) runs both valid and invalid sets through the Inspector and ensures results are correct - reports for the invalid cases, no reports for the valid cases. + +[An XSD schema ](testing/computer_metaschema-xmlschema.xsd) can also be used to confirm validity or failure to validate for sets of examples, as given. Any other metaschema-based validator, or a metaschema-derived validation that supports XML, can also be used, such as a validator produced using [metaschema-java](https://github.com/usnistgov/metaschema-java). + +Also, examples within `tinydata` may be valid or invalid to the Tiny metaschema, as indicated. + +### Templates and functions + +Question: *How do I know a specific report is being produced correctly by Inspector XSLT for a given error condition in 'computer XML' data?* + +Individual templates and defined functions can also be targeted and tested in XSpec. + +XSpec testing breaking out these cases, both 'go' and 'no-go', are located in [the inspector-functional testing directory](testing/tests/inspector-functional/) + +## Testing Inspector XSLT production + +Question: *Is the XSLT produced from a metaschema instance correct not only respect to its capabilities (addressing functional requirements) but also other requirements such as legibility, exception handling or post-processing features?* + +To the extent that 'correctly' is currently defined, it is in reference to functionality (see above) and relevant Metaschema specifications, not to an abstract design. + +However, a target for this transformation - generation of XSLT from correct Metaschema source data - can be defined and codified as a 'canonical form' of Inspector XSLT. To the extent this has been done, XSpec demonstrating conformance to the expressed requirements is given in [the inspector-generation testing directory](testing/tests/inspector-generation/) + +The [Inspector XSLT Generator Pipeline](../METASCHEMA-INSPECTOR-XSLT.xpl) includes a step that applies the generated XSLT and reports a finding of `OKAY` or `ERROR` as a pipeline result (on output port `OUT_xslt-prooftest`), as a convenience. + +## Testing the costuming post-processing pipelines + +Inspector XSLT first produces MX outputs. These are further processed, first by being filtered, then into HTML and Markdown results. + +These transformations can be tested. An HTML-to-Markdown XSpec could also be useful elsewhere. + +If these are not already to be found among the tests it remains a TODO item. diff --git a/src/schema-gen/InspectorXSLT/generator/generate-inspector-xslt.xsl b/src/schema-gen/InspectorXSLT/generator/generate-inspector-xslt.xsl new file mode 100644 index 00000000..18fb5ca0 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/generator/generate-inspector-xslt.xsl @@ -0,0 +1,996 @@ + + + + + + + + + + + + + + ../../../../support/metaschema + + + {$metaschema-repository}/schema/xml/metaschema-datatypes.xsd + + + + + + + + + + + + + + xs: + + + + + + Generated { current-dateTime() } + + + + + + + Templates copied from boilerplate + + + + + + + { /*/schema-name } + + + + + Generated rules - first, any roots + + + + Root + + + + + Occurrences - templates in mode 'test' + + + + + + + + + + + + + + + + + Fallbacks for occurrences of known elements and attributes, except out of + context + + + + + + gix.108 + EOOP element-out-of-place + Element { name() } is not permitted here. + + + + + + gix.117 + AOOP attribute-out-of-place + Attribute @{ name() } is not permitted here. + + + + + Definitions - a named template for each + + + + + Datatypes - a named template for each occurring + + + + + + + + + VDSX violates-datatype-syntax + + + + + + + + gix.148 + + + {{ $class }} + not({$assert}) + + Value {{ string(.) }} of {{ if (self::element()) then 'element' else 'attribute' }} {{ self::attribute()/'@' }}{{ name(.) }} does not conform to { $this-type } datatype. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + empty(following-sibling::{$using-name}) and (count(. | preceding-sibling::{$using-name}) lt {$min}) + + + gix.336 + EATI element-appears-too-infrequently + {$test} + + Element { mx:use-name(.) } appears too few times: { $min } minimum are required. + + + + + count(. | preceding-sibling::{$using-name}) gt {$max} + + gix.347 + EATO element-appears-too-often + {$test} + + Element { mx:use-name(.) } appears too many times: { $max } maximum { if + ($max eq 1) then 'is' else 'are' } permitted. + + + + + + + empty(preceding-sibling::{$using-name}) and exists(../({ + ($alternatives ! mx:use-name(.)) => string-join(' | ') })) + + gix.362 + {$test} + + VEXC violates-exclusive-choice + Element { mx:use-name(.) } + is unexpected along with + + + + . + + + + + + + + + + + + + + + exists({$interlopers}) + + gix.390 + EOOO element-out-of-order + {$test} + + Element { mx:use-name(.) } + is unexpected following + + + + . + + + + + + + + + + { mx:match-name(.) } + + + + + + + + + + + + + + + + + + + + + + + + + + empty({$requiring}) + + gix.445 + MRQC missing-required-contents + {$test} + + Element {{ name() }} requires element { $requiring + }. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + matching {name()}{ @id ! ('[@id=' || . || ']')} we get no template for the constraint cascade + + + + + + + + + { @target[not(matches(.,'^\s*\.\s*$'))] ! ('/(' || . || ')') + } + + + + + + .=({$value-sequence}) + + + + gix.502 + { @id } + { $target-match } + AVCV value-not-allowed + not({$assert}) + + Value {{ string(.) }}{{ .[not(string(.))] ! ' (empty)' }} does not appear among permissible (enumerated) values for this {{ name() }}: { $values => string-join('|') }. + + + + + + + + + + + + + { @target[not(matches(.,'\s*\.\s*'))] ! ('/(' || . || ')') + } + + + + + { parent::matches/@id } + MDCV datatype-match-fail + { $target-match } + + + + matches(., '^{.}$') + + gix.536 + { parent::matches/@id } + { $target-match } + MRCV regex-match-fail + not({$assert}) + + {{ string(.) }}{{ string(.)[not(.)] ! ' (empty)' }} does not match the regular expression defined for this {{ name() }}: { . }. + + + + + + + + + + + + { @target[not(matches(.,'\s*\.\s*'))] ! ('/(' || . || ')') + } + + { @test } + + + + + + gix.564 + { @id } + { $target-match } + XPKT expectation-violation + not({$assert}) + + Expression result for { $target-match } does not conform to expectation {@test}. + + + + + + + + + + + count({ @target }) + { + (@min-occurs ! ($count-expr || ' ge ' || .),'true()')[1] } and { + (@max-occurs ! ($count-expr || ' le ' || .),'true()')[1] } + + + + gix.589 + { @id } + { $matching } + HCCV cardinality-violation + not({$assert}) + + Counting { @target } under { $matching } finds {{{$count-expr}}} - expecting { @min-occurs ! ('at least ' || . || (../@max-occurs !', ')) }{ @max-occurs ! ('no more than ' || .) }. + + + + + + + + + + + + + + + + + mx:key-matches-among-items(.,$selected,'{$keyname}',{mx:key-value(.)},$within) + exists({$count-expr}) + + + + + + + gix.621 + { @id } + { string-join($matching,'|') }/({ @target}) + NXHK index-lookup-fail + not({$assert}) + + With respect to its assigned index { key-field[2]/'(compound) ' } value, this {{name(.)}} is expected to correspond within its {{$within/name(.)}} to a value listed under index { @name }. This index has no entry under the key value{ key-field[2]/'s' } {{string-join(({mx:key-value(.)}),',')}}. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mx:key-matches-among-items(.,$selected,'{$keyname}',({mx:key-value(.)}),$within) + count({$count-expr})=1 + + + + + + + + + + + gix.670 + { @id } + { string-join($matching,'|') }/({ @target}) + UNIQ uniqueness-violation + not({$assert}) + + With respect to its assigned { mx:key-value(.) }, this {{name(.)}} instance of { string-join($matching,'|') }/({ @target}) is expected to be unique within its {{$within/name(.)}}. {{count({$count-expr})}} items are found with the value{ key-field[2]/'s' } {{string-join(({mx:key-value(.)}),',')}}. + + + + + + + + + + + + , + + ({ @target//(.[not(. = ('.', 'value()'))], 'string(.)')[1] }) + [matches(.,'^{.}$')] ! replace(.,'^{.}$','$1') + + + + + + + + + + + + + + + true + + + + + + + NDX_ + + + + + + + UNQ_ + + + + + NDX_{@name} + + + UNIQ_{ @id } + + + + + + + + + + + + + + + + + empty(@{$requiring}) + + gix.748 + MRQA missing-required-attribute + {$test} + + Element {{ name() }} requires attribute @{ $requiring }. + + + + + + + Base64Datatype + BooleanDatatype + DateDatatype + DateTimeDatatype + DateTimeWithTimezoneDatatype + DateWithTimezoneDatatype + DayTimeDurationDatatype + DecimalDatatype + + + + EmailAddressDatatype + HostnameDatatype + IntegerDatatype + IPV4AddressDatatype + IPV6AddressDatatype + NonNegativeIntegerDatatype + PositiveIntegerDatatype + StringDatatype + TokenDatatype + URIDatatype + URIReferenceDatatype + UUIDDatatype + + + + Base64Datatype + DateTimeDatatype + DateTimeWithTimezoneDatatype + EmailAddressDatatype + NonNegativeIntegerDatatype + PositiveIntegerDatatype + + + + + + + + + + + + + + { xs:restriction/@base } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + string(.) castable as { $nominal-base-type } + + and matches(.,'^{ current-grouping-key() }$') + + + + + + + string(.) castable as {(xs:restriction/@base,@name)[1]} + + + + + + + + string(.) castable as {(xs:restriction/@base,@name)[1]}{ $extra[normalize-space(.)] ! (' and ' || .)} + + + + + + + + matches(.,'^{@value}$') + + + + + + + + + + + + + + + + + + + + + + + + + + , + + or + + + + + + { $n } + + + + + + + + + + + + + + + + { mx:match-name(ancestor::model[1]/..) }/{ mx:match-name(.) } + + + + /{ root-name } + + + + + + + + + + + + + + + { $who/group-as[@in-xml='GROUPED']/@name ! (. || '/') }{ mx:use-name($who) } + + + + + + + { ($who/group-as[@in-xml='GROUPED']/@name, mx:use-name($who))[1] } + + + + + { mx:use-name(.) } + + { group-as/@name }[exists({ mx:use-name(.) })] + + + + { $who/ancestor::model[1]/parent::*/(mx:match-name(.) || '/') }{ mx:match-name($who) } + + + + + + + + + + + . . . . . . . . . . . . . . . . . + + + + + + + + + . . . . . . . . . . . . . . . . . + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/generator/generator-boilerplate.xsl b/src/schema-gen/InspectorXSLT/generator/generator-boilerplate.xsl new file mode 100644 index 00000000..a50ba255 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/generator/generator-boilerplate.xsl @@ -0,0 +1,550 @@ + + + + + + inspected + + + full + + + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + av.152 + _UE unmatched-element + Unrecognized element { name() }. + + + + + + + + + + + + + + + + + + + + + + av.180 + _UT unexpected-text + Errant text content. + + + + + + + + + av.193 + _UA unmatched-attribute + Unrecognized attribute @{ name() } on element { name(..) }. + + + + + + + + + + + + exists(.) + + __U uncategorized + * + [info] + ERROR + + + + + + + + + + + + + + + + + + + [info] + + + + + + + + + + /{ name() } + + + + + + /{ name() }[{ mx:element-position(.)[count($kin) gt 1] }] + + + + + /@{ name() } + + + + + + [{ count(preceding-sibling::text()|.) }] + /text(){ (count($kin)[. gt 1]) ! $place } + + + + + + [{ count(preceding-sibling::comment()|.) }] + /text(){ (count($kin)[. gt 1]) ! $place } + + + + + + [{ count(preceding-sibling::processing-instruction()|.) + }] + /text(){ (count($kin)[. gt 1]) ! $place } + + + + + + + + + + + + + { $as } + { $as }s + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + File { replace(@src,'.*/','') } has { $error-count } { + mx:pluralize($error-count,'error')}. + File { replace(@src,'.*/','') } has { $report-count } { + mx:pluralize($report-count,'issue') } reported including { $error-count } { + mx:pluralize($error-count,'error')}. + + + + + + + + + + + File { replace(@src,'.*/','') } is reported VALID, no issues ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { (@level,'ERROR')[1] } [CLASS) { @class } ][PATH) { @xpath } ][REPORT) { + string(.) }] + + + + + + + + + + + + + + { $validating-filename } - { $checked } - { mx:metaschema/@shortname } validation + + + + +

{ $checked } Validating { $validating-filename } - { mx:metaschema } - found { + 'IN'[not($reported-valid)] }VALID

+ + +

{ $validating-filename } contains { @elements} { + mx:pluralize(@elements/number(),'element') } and { @attributes } { + mx:pluralize(@attributes/number(),'attribute') }.

+ + +
+ +
+
+
+ + +
+ + + + + + + + +
+

{ count(.//mx:report) } { mx:pluralize(count(.//mx:report),'issue') } reported.

+

+ + 💥 + +

+
+
+ + +
+

Good news - nothing to report - the instance is valid. 🚀

+
+
+ + + + + + +
+ + + +

{ @class }{ @level[not(.='ERROR')] ! (' ' || .) }

+
    + +
  • Rule ID: { . }
  • +
    +
  • test: { @test }
  • + +
  • matching: { @matching }
  • +
    +
  • XPath: { @xpath }
  • + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + { codepoints-to-string(10) } + + + + + + + + + + + { $lf } + + + + + { $lf2 }--- + + + + + # + + + + + + { $lf2 }# + + + + + + { $lf2 }## + + + + + + { $lf2 }### + + + + + + { $lf2 } + + + + + + + + + + + { $lf }- + + + + + ** + + ** + + + * + + * + + + ` + + ` + +
diff --git a/src/schema-gen/InspectorXSLT/generator/oscal-inspector-fixup.xsl b/src/schema-gen/InspectorXSLT/generator/oscal-inspector-fixup.xsl new file mode 100644 index 00000000..a33af04b --- /dev/null +++ b/src/schema-gen/InspectorXSLT/generator/oscal-inspector-fixup.xsl @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + catalog//part + + + catalog//prop + + + catalog//control | catalog//group | catalog//part + + + catalog//control + + + catalog//param + + + catalog//group + + + + + has-oscal-namespace\('http://csrc.nist.gov/ns/oscal'\) + + not(@ns!='http://csrc.nist.gov/ns/oscal') + + + { replace(.,$replacing-regex,$replacement) } + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/inspector-generator-checkup.sch b/src/schema-gen/InspectorXSLT/inspector-generator-checkup.sch new file mode 100644 index 00000000..337e6c14 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/inspector-generator-checkup.sch @@ -0,0 +1,22 @@ + + + + + + + + + + + + @cf missing when calling 'notice' template + + + + + 'cf' value is expected to be 'gix.' here. + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/mx-grabber.xsl b/src/schema-gen/InspectorXSLT/mx-grabber.xsl new file mode 100644 index 00000000..8f578167 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/mx-grabber.xsl @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/schema-gen/InspectorXSLT/mx-reporter.xsl b/src/schema-gen/InspectorXSLT/mx-reporter.xsl new file mode 100644 index 00000000..f63487b6 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/mx-reporter.xsl @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + +

Validation { @src ! replace(.,'.*/','') }

+

{ @src }

+

{ @elements } elements and { @attributes } attributes found in the document.

+ + + + +
+ + +
+

{ count(.//mx:report) } reports

+
+
+ + +

Metaschema: { . } (namespace '{ @namespace }')

+
+ + +
+

Good news - nothing to report - the instance is valid.

+
+
+ + +
+

{ @xpath }

+

{ @test }

+

+ +

+
+
+ + + + + + + +
diff --git a/src/schema-gen/InspectorXSLT/planning.md b/src/schema-gen/InspectorXSLT/planning.md new file mode 100644 index 00000000..6caebe12 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/planning.md @@ -0,0 +1,101 @@ +# Planning + + +## Feature set (for demo) + +- [x] Emit copy of source annotated with validation messages +- [x] Emit reports to STDOUT +- [x] Write reports to file system (lower ASCII, escaped HTML for emoji) +- [x] Emit reports in native (MX) format, HTML, Markdown or plain text (compacted Markdown) +- [x] Supports full, summary or one-line results per instance +- [x] Can echo progress as it writes +- [x] Run in batch + - [x] Using Saxon feature (writing files) + - [x] Using shell + - [ ] Using XProc + - [ ] make post-process XSLT digesting a sequence of MX results +- [x] Validate structures - names and cardinalities +- [x] Validate lexical rules over datatypes + - [ ] more testing +- [x] Validate constraints +- [ ] Run in browser / SaxonJS +- [ ] MX->SVRL filter postprocess +- [ ] other ideas below + + +### To do: further work on scripting + +Instrument to run from the CL, inferring the mode from the result filename and hard wiring the `computer-inspector.xsl` stylesheet: + +``` +computerInspectorXSLT data.xml results.html +computerInspectorXSLT data.xml results.md +computerInspectorXSLT data.xml results.xml + +computerInspectorXSLT -md data.xml (writes results to STDOUT) +computerInspectorXSLT -mx data.xml (writes results to STDOUT) +computerInspectorXSLT -html data.xml (writes results to STDOUT) +computerInspectorXSLT -md data.xml mode=one-liner +``` + +This all ought to be doable in `make`, no? + +Alternatively, note that *these scripts as well* might be generated from Metaschema source as they are mostly boilerplate. So to the extent they can be produced on the basis of `/METASCHEMA/short-name` etc. we should consider doing that. + +## Plans + +### Functional enhancements + +- Filters to sort, sift? +- HTML aggregation layer? over collections +- CSS customization (CSS-based filtering?) +- or all this could be done dynamically (CSX) + +### Under NodeJS + +It could also be compiled into SEF for SaxonJS and delivered as a NodeJS command line application or library + +### In the browser - CSX (client-side XSLT) + +Another SEF with interface and SVRL rendering templates could provide this functionality under SaxonJS in the browser. + +See https://pages.nist.gov/oscal-tools/demos/csx/validator/ for prior work/PoC. + +### XProc / XML Calabash + +For batching and post-processing validations using an XSLT, the sky is the limit. + +### Python runtime? + +How hard can it be? + +### OSCAL application + +Should go into oscal-xslt repository + +### JSON support? + +One approach could be to produce templates not to match XML (that is or is not conformant to expectations) but JSON (that is or is not conformant to the metaschema-analogous expectations). + +JSON could first be cast into an XDM map, so this operation conceivably could mean an XSLT generator whose output XSLT would match not nodes but objects (properties) in this map - checking to see whether they resolve to maps, arrays and values as planned - and whose templates indeed would perform a 'map traversal'. + +### Line numbers + +Alas, can't get line numbers in Saxon-HE. We could provide optional line number echoing potentially in a version requiring licensed Saxon. + +### XSLT 1.0? + +We know that we can't do everything under XSLT 1.0 (such as regular expressions for lexical type checking) but we might be able to provide a significant subset, as a "sine qua non" first-cut validator. + +--- + +notes - combinatorial allowed-values implementation + +inspector XSLT carries a template cascade +- it reports back both values and IDs +- the cascade overloads priority="100" for competing `allowed-values` + mode has on-multiple-match="use-last" so that they can be made (purposefully) to compete (last wins) + - these must all be identical so an effective no-op when redundant + - any/each of which (only one of them being used under use-last) pulls the entire collection of values/IDs matching this node + + diff --git a/src/schema-gen/InspectorXSLT/readme.md b/src/schema-gen/InspectorXSLT/readme.md new file mode 100644 index 00000000..902b2d03 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/readme.md @@ -0,0 +1,405 @@ +# Metaschema XSLT Inspector + +Check your XML with an XSLT to see if it is valid to the rules defined in a metaschema. + +Developers are urged to review this file in outline before reading it in detail. For experienced XSLT developers, it explains the interfaces. For beginners, it should tell you what you need to know. Any sections not of immediate interest can be skipped for later. + +## How this works + +A standalone XSLT ("stylesheet" or transformation specification) can be produced by applying a stylesheet (an XSLT) to a metaschema. Using the composition pipeline, it can apply to a top-level module of a modular metaschema. + +The XSLT that is created this way can be used to test XML instances for errors in view of the rules defined by the metaschema definitions. + +* Element and attribute types, structures and content models + * Occurrences and cardinalities of attributes and elements + * Detection of unrecognized tagging + * Detection of tagging out of place +* Lexical data type (castability) checks +* Constraints defined in the metaschema including compound and contingent constraints, co-occurrence, and key-based (referentiality) constraints + +That is, it combines the effective functionality of XML schema and Schematron (XPath-based) validation. + +## Limitations + +Aiming at a complete and conformant implementation for XML of the [Metaschema](https://pages.nist.gov/metaschema) language version 1.0, there are a few known gaps, with a testing framework and protocols now being established both for filling those gaps and for demonstrating the tool's full functionality. Please use the processor with this in mind, that developers and sponsors need your feedback and contributions to enable us to complete the work. + +Currently we plan to support only XML-based formats as defined by Metaschema, not their semantically-equivalent JSON or YAML 'cousins'. + +Users of Metaschema-defined JSON can try reformatting their data as XML using automated means such as scripts produced by the [Metaschema XSLT Converter Generators](../../converter-gen). Successful conversion will be valid on the other side. But failures will be indicated not typically be invalid results, and instead results missing those parts of the invalid that went unrecognized by the converter because they are invalid. + +## Demo + +The [testing/current](testing/current) directory shows such an XSLT, which can be applied to an instance or set of instances (documents) to be tested against the rules defined by its metaschema - in this case the Computer Model metaschema example provided. + +Alternatively, follow the directions to build an XSLT reflecting the rules of any other metaschema, with which XML conforming to those rule sets may be validated. + +See the [Metaschema project site](https://pages.nist.gov/metaschema) for more information. + +## Note for OSCAL users + +While the intent of this project is to support OSCAL\* formats fully, and OSCAL will be an important testbed for these applications, the OSCAL Metaschema modules given in the current version (1.1.1) do *not* process flawlessly (as of the beta-version Inspector Generator) to produce a viable InspectorXSLT rules checker, without patching. + +See [the tracking issue](https://github.com/usnistgov/metaschema-xslt/issues/91) for any updates, with possible mitigations for those interested. + +\* OSCAL is the [Open Security Controls Assessment Language](https://pages.nist.gov/OSCAL/), a family of schemas describing documentary formats in Systems Security - Catalogs, Profiles (baselines or overlays), System Security Plans (SSP), Security Assessment Plans (SAP) and Reports (SAR), and others. + +## Project purposes + +While this project offers a tool that may be useful (for data validation) its ultimate focus is not the data validation as such, but to demonstrate principles of verifiable and trustworthy data validation. + +A primary goal of this project is to serve as a complete and correct implementation of the [NIST Metaschema Modeling Framework](https://pages.nist.gov/metaschema), in demonstration of its features, with the objective of helping to confirm, by testing, its approach to data modeling and governance. + +A secondary goal is to be fully transparent and traceable in operation and documented and tested fully, so as to serve as a resource and template for future developers of Metaschema, XML/XSLT and other technologies. + +Neither *scalability* nor *performance* are primary goals, although considered valuable and worth working for. + +Given these considerations on balance, *correctness* comes first in order of priority, while *usability* and *testability* come second and third. + +### Who are you? some possible use scenarios + +- New, occasional, or intermittent users of a Metaschema-based tech, who need to validate data +- Regular users of a metaschema or Metaschema-based tech + - who need to validate data + - who need to confirm the correctness of others' validations +- Developers of Metaschema-based applications + - who wish to use or deploy an easy validation service + - who prefer to focus on implementing semantics, not on modeling and validating to models - but who need to provide for data validation and support others in doing so +- Developers of Metaschema + - who want more tools, + - who need and expect diversity in a healthy standards ecosystem + - and who wish to compare implementation strategies and approaches +- XSLT/XSpec students and developers + - since the codebase aims to be transparent and traceable as well as useful in operation + +### Aims + +For new, regular and occasional users and developers of Metaschema-based technologies + +* InspectorXSLT and MX\* aim to be easy to use and start using +* Correct and trustworthy in what it attempts to do +* And compatible with workflows using other conformant tools + +For developers and maintainers of Metaschema-based data modeling and processing stacks, this tool (and all tools in the repo) aspires + +* To be lightweight, easy to deploy, easy to adapt and useful, +* To be versatile (given its scope of application, namely validation) +* And to serve as a complement to other Metaschema tools and applications\* + +For XML- and XSLT-focused developers of Metaschema and Metaschema-based technology + +* MX is open, in the public domain, and standards-based +* And aims to be fully and openly tested + +\* Applications to consider using along with InspectorXSLT include the schema and converter-stylesheet generators in this repository as well as tools from other developers. MX can even check against itself by validating documents with both the Inspector and its XSD - the same issues should be reported over invalid data (insofar as the XSD is able to express them) using either tool. + +### Use cases we have not catered to + +- Developers who wish to build metaschema-aware applications + - This application is intended to be operated as a black box: while at core this is a code generator, it is not designed to be easily extensible as such or produce a 'library', so you might prefer to reverse engineer it than to extend it +- Robots or 'lights out' automated processes (untested) + - The interfaces are designed to be flexible for interfacing but YMMV as to scale/throughput - experience will tell + - Our expectation is that performance will be good under normal loads but metaschemas will also vary considerably + +## Feature set (for demo) + +- Emit copy of source annotated with validation messages +- Emit reports to STDOUT +- Write reports to file system (lower ASCII, escaped HTML for emoji) +- Emit reports in native (MX) format, HTML, Markdown or plain text (compacted Markdown) +- Supports full, summary or one-line results per instance +- Can echo progress as it writes +- Run in batch + - Using Saxon feature (writing files) + - Using shell + - (tbd) Using XProc + - (tbd) make post-process XSLT digesting a sequence of MX results +- Validate structures - names and cardinalities +- Validate lexical rules over datatypes +- Validate constraints as defined by Metaschema + - allowed values; string matching; referential integrity; arbitrary queries (assertions) + +## Interfaces - how to use + +### Schematron harness + +InspectorXSLT was engineered to be used as a standalone XSLT, for maximum usability. Of course this means it can be also be embedded. And since Schematron is commonly deployed as an XSLT application, a full-fledged Schematron-based implementation is feasible as a possible follow-on application. + +A simple wrapper Schematron that calls the InspectorXSLT for you and delivers its messages in a Schematron process, is even easier to engineer, and [one has been included](testing/computer-testing.sch) here in the [`testing`](testing/) folder. + +### Shell scripts + +The tool is designed to be used standalone in an XSLT 3.0-capable processing environment, or to be embedded. For testing, we use a command-line XSLT engine such as Saxon (v10 or later). We test with Saxon-HE in order to ensure this execution dependency remains available. + +For convenience, in the testing directory are example scripts that run Saxon inside Maven to (a) produce an Inspector XSLT from a metaschema, then subsequently (b) apply this XSLT to an XML document to report issues detected in it, to delivering this report in HTML or Markdown format: + +- `testing/refresh-computer-inspector.sh` refreshes "computer metaschema" example XSLT +- `testing/inspect-computer.sh aComputerXML.xml format=md` applies this XSLT to a 'computer' XML document returning Markdown +- `testing/inspect-computer.sh aComputerXML.xml -o:report.html format=html` applies this XSLT to a 'computer' XML document, and writes an HTML report to a file called `report.html` +- with many more options - see script help or more info below + +These scripts demonstrate one way to invoke Saxon but there are many others suited to different operational contexts and systems, including other deployments of Saxon (Saxon-C or SaxonJS, just to name two). + +The scripts also pass through arguments provided them to the receiving application, so that the flags and switches described below will also work. + +### Command-line XSLT execution + +If a script is not well-suited or easily adaptable, or for testing/experiment, Saxon can also be used directly, using the same syntax (which the scripts mainly pass through). + +#### Summary + +Command line flags and options for using the InspectorXSLT with Saxon - note use of `:` and `=` and an ordering requirement, that all parameters (`param=`) be placed after all flags (`-flag:`), while the order of parameters or flags otherwise does not matter. + +##### Flags for source, output, alternative entry points + +- `-s` required flag indicates the source file or directory - if a directory, `-o` is also required +- `-o` optional flag indicates where to write a report file; if omitted the report comes back to STDOUT; required when `-s` is a directory +- `-it` (or `-initial-template`) settings are supported as aliases of the `format` parameter (see below). If `format` is not given, a template can be called by name to initiate the same behavior. This is mainly useful for debugging or to configure a different fallback behavior from the core default in deployment. + +##### Parameters + +Runtime parameters dictate the behavior of the transformation engine and the transformation results + +- `format=markdown` and `format=md` produce Markdown +- `format=plaintext` drops double line-feeds from the Markdown producing a plain text format (or `format=plain` or `format=text`) +- `format=html` produces HTML (or `webpage` in case you are guessing) +- `format=mx-report` or `format=mx` produce (the same) report in an MX XML format, suitable for further processing +- `format=inspected` returns a copy of the input with metadata regarding the validation and validation reports embedded + +The fallback behavior, if no format is indicated via `format` (or an initial template), is `inspected`, producing an annotated copy. This is also the simplest operation, which makes it easiest to debug. + +The `form` parameter provides for adjustments to be made to outputs (HTML, Markdown or plaintext): + + - `form=summary` suppresses all details and presents only a summary + - `form=one-line` suppresses everything but a single summary line + - Otherwise a form value `full` is inferred and the full results included + +The `echo` parameter can be used to supplement output reports with messages to the console. This feature is *complementary* to the basic reporting and is expected to be used along with it, especially when reports are written to files. + + - `echo=none` or no `echo` parameter provides no echo + - `echo=docs` reports an instance found valid or invalid + - `echo=invalid-only` reports an instance found invalid + - `echo=info` reports the valid/invalid finding plus info messages + - `echo=warnings` reports the valid/invalid finding plus warnings and info messages + - `echo=all` (or any `echo` other than `none`) reports the finding plus all errors, warnings and info messages + +When producing HTML reports, a file name reference to an out-of-line CSS resource can be provided. It will drop from HTML outputs the inlined CSS, and instead provide a link to the named resource. Provide a CSS file with that name to control all the styling of the reports. + + - `css=cssfile.css` replaces CSS in your HTML header with `\`. + +TBD, to be considered (let us know): + + - filters to remove messages by level, code or matched node (XPath) + +#### Tweaking result file names + +Saxon supports the excellent feature of processing an entire directory of inputs at a time, with the limitation that result files (validation reports in this application) are named after the source files from which they are produced. + +Especially when Markdown or HTML results are produced in batch with names matching the names of XML inputs, it can be useful to follow a directory-level operation with a global renaming of `.xml` to `-report.html` (or `-report.md` etc.). The many ways to do this include (in \*nix systems) a bash script invoked inside a subshell: + +``` +(cd reports && for f in $(ls *.xml); do mv $f ${f%.*}-report.html; done) +``` + +`reports` being the path to the directory where the misnamed files can be found. + +It is possible to use this technique with a script as well: + +``` +(cd ready && for f in $(ls *.xml); do ./inspect-computer.sh -im:md -s:$f form=one-line; done) +``` + +In this case, `*.xml` files in the `ready` folder are run through the Inspector with a one-line Markdown report offered back. + +Of course this also not the only way to automate the validation and reporting processes for efficiency over many inputs in one run. + +#### Example scenarios calling Saxon + +Various different command-line options can modify operations, either using Saxon and runtime parameters directly, or through scripting. + +The XSLT initial template feature, XSLT runtime parameters, and redirecting processing results together provide a range of capabilities. + +In the examples below, syntax for many of these is shown. This assumes `saxon` is available as an executable, such as a script that calls Saxon in Java or Maven: adjust as needed. + +Having produced the XSLT `computer-inspector.xsl` for inspecting `computer` XML documents: **to validate a file** `invalid10.xml` ... + +--- + +**Bring back a copy of the input annotated** with MX (XML) results to STDOUT. + +```bash +saxon -xslt:computer-inspector.xsl -s:invalid10.xml +``` + +--- + +**Bring the messages only.** `-it:mx-report` does the same. `-it` designates an initial template. For convenience the Inspector XSLT also supports `-im` (designating an initial mode) with the same values and effects. If both are given the processor uses `-it`. + + +```bash +saxon -xslt:computer-inspector.xsl -s:invalid10.xml format=mx +``` + +--- + +**Write MX (XML) results (only) to a file** `results.xml`: + + +```bash +saxon -xslt:computer-inspector.xsl -s:invalid10.xml -o:results.xml format=mx +``` + +This can be useful to capture MX reports for further processing. + +--- + +**Write HTML results to a file** `results.html`. Use `!method:html !html-version:5.0` to get HTML 5 output instead of XML. (Or `!method:xhtml` if preferred.) Use `!indent:true` if you don't want a code brick. + + +```bash +saxon -xslt:computer-inspector.xsl -s:invalid10.xml -o:results.html format=html +``` + + +Note that HTML and Markdown results presuppose the MX filtering step - they do not present a copy of the document being validated. + +--- + +To **write Markdown results to STDOUT**. (Note lack of `-o` argument.) This is the same as `-it:markdown`: + +```bash +saxon -xslt:computer-inspector.xsl -s:invalid10.xml format=md +``` + +--- + +To write **Markdown results to STDOUT except emit *one line only***. This uses the `form` parameter.: + +```bash +saxon -xslt:computer-inspector.xsl -s:invalid10.xml form=one-line format=md +``` + +--- + +And to **silence results entirely when a file is found to be valid**: + +```bash +saxon -xslt:computer-inspector.xsl -s:invalid10.xml -o:/dev/null echo=invalid-only +``` + +--- + +Or instead to **echo warnings and info** (only) to the console but otherwise silence results: + +```bash +saxon -xslt:computer-inspector.xsl -s:invalid10.xml -o:/dev/null echo=warnings +``` + +Why would you want to do this? Because you know of errors already but want an update regarding any warnings. + +--- + +To **run over a set of files** in a folder named `to-validate` and produce result (files) in a new folder, `reports` (with Markdown reports): + +```bash +saxon -xslt:computer-inspector.xsl -s:to-validate -o:reports format=md +``` + +Note - results are written for all files, valid and invalid, irrespective of findings. Extra empty files can be fairly easily removed with a utility. + +--- + +To **report as files are found to be valid or invalid** to STDOUT, *additional* to producing reports. + +The `echo` feature is useful when using the `-o` argument to direct outputs (complete or summaries) to file or device. Additional to the primary outputs, `echo` produces a record and summary view to a secondary output, generally STDERR (via `xsl:message`). + +This can be helpful when validating inputs in batches and writing results to files. Often an operator prefers to have some runtime notification of what is happening, even when the main interest is in 'side effects' such as files written to the system. + +Use `echo` if you wish to see progress in the console even when directing results to file outputs. It will announce findings of both valid and invalid files, one line per file, in addition to other messages; so it can be similar to `form=one-line` except it supplements instead of replaces the production of complete reports (i.e., the primary result) - so progress can be monitored in the same run as results are written out. + +`echo` and `form` can be used at the same time - `form` affecting how results look, and `echo` affecting what gets reported via messaging along with that production. + +--- + +Alternatively, to **use bash to loop over one file at a time, collecting the outputs coming to STDOUT** to a file. + +With `form=one-line` and Markdown or plaintext results, we get one line per file. + +```bash +(for f in $(ls collectionls /*.xml); do saxon -xslt:computer-inspector.xsl -s:$f format=md form=one-line; done) 1> validated.txt +``` + +--- + +Or running without `form=one-line` to **create a single Markdown report** (note result file name) - `echo` settings are available: + + +```bash +(for f in $(ls collection/*.xml); do saxon -xslt:computer-inspector.xsl -s:$f format=md echo=all; done) 1> validation-report.md +``` + +This time, all results are written in Markdown into the file `validation-report.md`, while `echo=all` provides progress indicators echoed to the console. Use other `echo` settings for less noise. + +--- + +There is much else that can be done to produce **batched and grouped reports** including analytical summaries, etc., by aggregating and post-processing MX, HTML or Markdown outputs. + +### To generate an Inspector XSLT + +A fresh and complete Inspector XSLT for any metaschema (any valid and workable instance of [Metaschema](https://pages.nist.gov/metaschema/)) can be produced using an XProc pipeline or an XSLT that emulates this pipeline. + +- ../METASCHEMA-INSPECTOR-XSLT.xpl +- ../nist-metaschema-MAKE-INSPECTOR-XSLT.xsl + +In this sequence of transformations the target (result) XSLT is assembled dynamically, by combining templates produced from a metaschema source with static boilerplate and infrastructure. + +An example script calling the XSLT pipeline (thus requiring only Saxon, not XML Calabash) is given as [testing/mvn-refresh-computer-inspector.sh](testing/refresh-computer-inspector.sh). + +## Design goals and principles + +The tool should be both easy to use and verifiably correct. + +("Easy to use" being relative, possibly the goal is "easy to make easy to use", with one or two easy-to-use ways to use it.) + +No need to quit after first error; take advantage of the 'pull' process (random access to tree) to give a complete picture of a document's state vis-a-vis validation requirements. + +The aims of the reporting are clarity/ease of use; to be unambiguous; to be traceable. To be concise and economical is a secondary goal. + +Reporting can be parsimonious - no need to be exhaustive. + +At the same time, errors anywhere are of interest (see 'no need to quit'). Some amount of redundancy is okay if not too noisy. + +### Theoretical considerations + +XSLT as validation language. + +This is a very different model of validation from what is usually (yet) practiced over data sets in exchange, even XML data except in some specialized circumstances. (There are noteworthy exceptions such as the NISO JATS, PMC and JATS4R technology cluster, or within DITA.) In considering the strengths, weaknesses and feature set of the tool, it may help to keep these differences in mind. What may be interesting is that this model - here called the pull model of validation - while very different from the usual historic model (for which we are using the shorthand push), is also very complementary to it. A mature and capable system can have uses for both models in combination. + +Setting aside the question of what should be meant by the pull model and why call it pull - this is *somewhat* analogous to push and pull parsing, two different techniques for building interpreters for character streams aka text processing - suffice it to say here that one aspect of pull is that conceptually, the data set under examination has already been parsed and is already available for inspection. This is not paradoxical if the push model is also in place, as long as a document can be read well enough to push into memory once, where it can be pulled. Fortunately, the syntactic rules of XML well-formedness are sufficiently well-defined that this is feasible. + +So in the field we work first by determining that an artifact purportedly and apparently XML is in fact XML - which we do, typically, with a neutral parse or 'well-formedness check'. (Indeed every day XML tools are doing this for their operators without their direct awareness.) While a low threshhold for interpretability - XML syntax assures nothing about an artifact other than its *potential* use *as XML* - this is significantly more than zero. Indeed this small bit of information is both critical (it means much more than it seems to on the surface), and *actionable* - it is consequential knowledge the enables further steps. + +Traditional push-based validation such as XSD validation is defined in such a way that it can be conducted as a document is parsed for the first time - that is, without reference to any prior representation of anything in the document after the reading position. It is as if a human reader of a novel were required never to go back in the book, or skip ahead, and more importantly never read again a book with any prior knowledge acquired in a first reading. (All books must only be read once through for the first time.) A read-once parse is a powerful and enabling capability - helping to manage, among other things, the complexity of memory requirements for the parse relative to document size - yet this comes at a steep cost for expressibility. Pull parsing assumes that once the book is available, reading and rereading are both natural and cheap. And in operation it proves indeed this is a tenable assemption as long as information sets do not grow too large and corpora too complex. (At that point other measures become necessary as well.) + +To validate truly arbitrary constraints up to and including so-called 'business rules', in which complexity of rules explodes and far-removed components within the document-space may be related, more or less requires that we do more. That is, any rules we wish to assert over documents that require or imply *random access* to document contents (both before and after the point under examination or enforcement), cannot be provided for by a bare grammar (which is what push parsers often depend on) without the fuller capabilities of a transformation language capable of querying, binding variables, caching and the rest. + +Interestingly, this different perspective on the rule set leads to different strengths and weaknesses in deployment between this application and standard approaches to document validation including XSD, RNG and DTD -- strengths and weaknesses that being opposite from the currently most common approach, also complement it. Indeed the successful use of Schematron, as another XSLT-transpiler, already shows this. + +If any of this is true, the application will show. + +### Advantages + +- Open-endedness with respect to arbitrariness of rules including contingent and co-occurrent rules +- Ease of post processing for presentation +- Flexible deployment, adaptable to different uses and workflows +- Complementarity with other approaches (since two opinions are better than one and more than double when they're the same) +- OSS platform (Saxon-HE) on Java, NodeJS, C/.NET/Python +- Tested and testable + +### Disadvantages + +- Doesn't do JSON - yet +- Limits on input sizes - very large inputs must still be chunked +- Potential performance tradeoffs for some kinds of rules +- Does not instantiate metaschema-based objects but only examines their representation (lexical form as a serialization) - so it is not as easily extensible as an application framework + +--- diff --git a/src/schema-gen/InspectorXSLT/report-validation-html.xsl b/src/schema-gen/InspectorXSLT/report-validation-html.xsl new file mode 100644 index 00000000..4a4769e6 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/report-validation-html.xsl @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + +
+ + +

Element (tree) structure (with validation findings)

+
    + + +
  • elements: { count($elements) }
  • +
  • attributes: { count($elements/@*) }
  • +
  • findings: { count($findings) }
  • +
    +
+ +

Congratulations: there is nothing to report

+
+ +
+ XML source +
+                    
+                
+
+ +
+
+ + +
+
{ name() }
+
+ +
+
+
+ + +
+

{ @cat }

+

+ +

+

{ @xpath }

+
+
+ + + + + + + + + + + + + + + + + + + +
{ normalize-space(.) }
+
+ +
diff --git a/src/schema-gen/InspectorXSLT/testing/.gitignore b/src/schema-gen/InspectorXSLT/testing/.gitignore new file mode 100644 index 00000000..f249fca7 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/.gitignore @@ -0,0 +1,5 @@ +# XSpec reports + +/*-result.html +/*-report.html +xspec/ diff --git a/src/schema-gen/InspectorXSLT/testing/COMPUTER-INSPECTOR-PRODUCE.xpl b/src/schema-gen/InspectorXSLT/testing/COMPUTER-INSPECTOR-PRODUCE.xpl new file mode 100644 index 00000000..025806c9 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/COMPUTER-INSPECTOR-PRODUCE.xpl @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/testing/CURRENT-TEST-MODELS-REFRESH.xpl b/src/schema-gen/InspectorXSLT/testing/CURRENT-TEST-MODELS-REFRESH.xpl new file mode 100644 index 00000000..db371d26 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/CURRENT-TEST-MODELS-REFRESH.xpl @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/testing/INSPECTOR-XSLT-TEST.xpl b/src/schema-gen/InspectorXSLT/testing/INSPECTOR-XSLT-TEST.xpl new file mode 100644 index 00000000..cf097793 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/INSPECTOR-XSLT-TEST.xpl @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/testing/TEST-INSPECTOR-RUNTIME.xpl b/src/schema-gen/InspectorXSLT/testing/TEST-INSPECTOR-RUNTIME.xpl new file mode 100644 index 00000000..07380b31 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/TEST-INSPECTOR-RUNTIME.xpl @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid1.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid1.xml new file mode 100644 index 00000000..67dfd5b0 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid1.xml @@ -0,0 +1,12 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ +
+
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid10.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid10.xml new file mode 100644 index 00000000..1a08bf08 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid10.xml @@ -0,0 +1,35 @@ + + + + type0 + + product-name0 + architecture0 + -5GHz + + + product-name1 + type1 + + + product-name2 + 50 + + + product-name3 + 50 + + + + + + + product-name4 + type2 + + + product-name5 + type3 + + + diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid2.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid2.xml new file mode 100644 index 00000000..3b1e3afc --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid2.xml @@ -0,0 +1,33 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ AT + + + name1 +
address1
+ http://pages.nist.gov/metaschema +
+ product-name0 + architecture0 + 5GHz +
+ + + name3 +
address3
+ http://pages.nist.gov/metaschema +
+ product-name2 +
+ +
+
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid3.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid3.xml new file mode 100644 index 00000000..d4d61453 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid3.xml @@ -0,0 +1,67 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ atxx + + + name1 +
address1
+ http://pages.nist.gov/metaschema +
+ product-name0 + architecture0 + 5GHz +
+ + + name2 +
address2
+ http://pages.nist.gov/metaschema +
+ product-name1 + type1 +
+ + + name3 +
address3
+ http://pages.nist.gov/metaschema +
+ product-name2 + 50 +
+ + + name4 +
address4
+ http://pages.nist.gov/metaschema +
+ product-name3 + 50 +
+ + + name5 +
address5
+ http://pages.nist.gov/metaschema +
+ product-name4 + type2 +
+ + + http://pages.nist.gov/metaschema + + product-name5 + type3 + +
+
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid4.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid4.xml new file mode 100644 index 00000000..b09b9dd3 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid4.xml @@ -0,0 +1,69 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ at + + + name1 +
address1
+ http://pages.nist.gov/metaschema +
+ product-name0 + architecture0 + 5GHz +
+ + + name2 +
address2
+ http://pages.nist.gov/metaschema +
+ product-name1 + type1 +
+ + + name3 +
address3
+ http://pages.nist.gov/metaschema +
+ product-name2 + 50 +
+ + + name4 +
address4
+ http://pages.nist.gov/metaschema +
+ product-name3 + 50 +
+ + + name5 +
address5
+ http://pages.nist.gov/metaschema +
+ product-name4 + type2 +
+ + + name6 +
address6
+ http://pages.nist.gov/metaschema +
+ product-name5 + type3 +
+
+
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid5.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid5.xml new file mode 100644 index 00000000..4304dd7c --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid5.xml @@ -0,0 +1,69 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ at + + + name1 +
address1
+ http://pages.nist.gov/metaschema +
+ product-name0 + architecture0 + 5GHz +
+ + + name2 +
address2
+ http://pages.nist.gov/metaschema +
+ product-name1 + type1 +
+ + + name3 +
address3
+ http://pages.nist.gov/metaschema +
+ product-name2 + 50 +
+ + + name4 +
address4
+ http://pages.nist.gov/metaschema +
+ product-name3 + 50 +
+ + + name5 +
address5
+ http://pages.nist.gov/metaschema +
+ product-name4 + type2 +
+ + + name6 +
address6
+ http://pages.nist.gov/metaschema +
+ product-name5 + type3 +
+
+
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid6.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid6.xml new file mode 100644 index 00000000..849291ad --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid6.xml @@ -0,0 +1,68 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ at + + + name1 +
address1
+ http://pages.nist.gov/metaschema +
+ product-name0 + architecture0 + 5GHz +
+ + + name2 +
address2
+ http://pages.nist.gov/metaschema +
+ product-name1 + type1 +
+ + + name3 +
address3
+ http://pages.nist.gov/metaschema +
+ product-name2 + 50 +
+ + + name4 +
address4
+ http://pages.nist.gov/metaschema +
+ product-name3 + 50 +
+ + + name5 +
address5
+ http://pages.nist.gov/metaschema +
+ product-name4 + type2 +
+ + + name6 +
address6
+ http://pages.nist.gov/metaschema +
+ product-name5 + type3 +
+
+
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid7.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid7.xml new file mode 100644 index 00000000..3b5baf85 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid7.xml @@ -0,0 +1,70 @@ + + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ atx + + + name1 +
address1
+ http://pages.nist.gov/metaschema +
+ product-name0 + architecture0 + 5GHz +
+ + + name2 +
address2
+ http://pages.nist.gov/metaschema +
+ product-name1 + type1 +
+ + + name3 +
address3
+ http://pages.nist.gov/metaschema +
+ product-name2 + 50 +
+ + + name4 +
address4
+ http://pages.nist.gov/metaschema +
+ product-name3 + 50 +
+ + + name5 +
address5
+ http://pages.nist.gov/metaschema +
+ product-name4 + type2 +
+ + + name6 +
address6
+ http://pages.nist.gov/metaschema +
+ product-name5 + type3 +
+
+
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid8.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid8.xml new file mode 100644 index 00000000..3b1a6a2c --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid8.xml @@ -0,0 +1,70 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ atx + + + name1 +
address1
+ http://pages.nist.gov/metaschema +
+ product-name0 + architecture0 + 5GHz +
+ + + name2 +
address2
+ http://pages.nist.gov/metaschema +
+ product-name1 + type1 +
+ + + name3 +
address3
+ http://pages.nist.gov/metaschema +
+ product-name2 + 50 +
+ + + name4 +
address4
+ http://pages.nist.gov/metaschema + http://pages.nist.gov/metaschema +
+ product-name3 + 50 +
+ + + name5 +
address5
+ http://pages.nist.gov/metaschema +
+ product-name4 + type2 +
+ + + name6 +
address6
+ http://pages.nist.gov/metaschema +
+ product-name5 + type3 +
+
+
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid9.xml b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid9.xml new file mode 100644 index 00000000..06b099c3 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-invalid/invalid9.xml @@ -0,0 +1,40 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ custom + + + name4 +
address4
+ http://pages.nist.gov/metaschema +
+ product-name3 + 50 +
+
+ + + name6 +
address0
+ http://pages.nist.gov/metaschema +
+ type0 + + + name8 +
address4
+ http://pages.nist.gov/metaschema +
+ product-name3 + 50 +
+
+
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-testing.sch b/src/schema-gen/InspectorXSLT/testing/computer-testing.sch new file mode 100644 index 00000000..baf4bc2a --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-testing.sch @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/testing/computer-valid/valid1.xml b/src/schema-gen/InspectorXSLT/testing/computer-valid/valid1.xml new file mode 100644 index 00000000..14b0f0df --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-valid/valid1.xml @@ -0,0 +1,60 @@ + + + 2023-10-31T11:15:30.069033200-04:00 + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ at + + + name1 +
address1
+ http://pages.nist.gov/metaschema +
+ product-name0 + x86 + 4.5GHz +
+ + + Socketeer +
address2
+ http://pages.nist.gov/metaschema +
+ Socketeer I + pata +
+ + product-name2 + 512 + + + product-name4 + 512 + + + product-name4 + 512 + + + product-name4 + 512 + + + + + + + name5 +
address5
+ http://pages.nist.gov/metaschema +
+ product-name4 + pci +
+
+ +
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-valid/valid2.xml b/src/schema-gen/InspectorXSLT/testing/computer-valid/valid2.xml new file mode 100644 index 00000000..ff7729c8 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-valid/valid2.xml @@ -0,0 +1,26 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ mini-itx + + + name4 +
address4
+ http://pages.nist.gov/metaschema +
+ product-name3 + 2048 +
+ + product-name3 + 2048 + +
+ +
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-valid/valid3.xml b/src/schema-gen/InspectorXSLT/testing/computer-valid/valid3.xml new file mode 100644 index 00000000..8b7861b1 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-valid/valid3.xml @@ -0,0 +1,56 @@ + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ mini-itx + + + name1 +
address1
+ http://pages.nist.gov/metaschema +
+ product-name0 + x86 + 10MHz +
+ + + SprocketSocket +
address2
+ http://pages.nist.gov/metaschema +
+ SprocketSocket + pata +
+ + + name3 +
address3
+ http://pages.nist.gov/metaschema +
+ product-name2 + 512 +
+ + product-name2 + 512 + + + + name5 +
address5
+ http://pages.nist.gov/metaschema +
+ product-name4 + pci +
+
+ +
diff --git a/src/schema-gen/InspectorXSLT/testing/computer-valid/valid4.xml b/src/schema-gen/InspectorXSLT/testing/computer-valid/valid4.xml new file mode 100644 index 00000000..f3b0cc85 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer-valid/valid4.xml @@ -0,0 +1,46 @@ + + + + atx + + product-name0 + x86 + 5GHz + + + SprocketSocket + pata + + + SprocketSocket + pata + + + product-name2 + 1024 + + + product-name3 + 1024 + + + + + + + + + + + + + product-name4 + pci + + + product-name5 + pcie + + + + diff --git a/src/schema-gen/InspectorXSLT/testing/computer_metaschema.xml b/src/schema-gen/InspectorXSLT/testing/computer_metaschema.xml new file mode 100644 index 00000000..cf28f073 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/computer_metaschema.xml @@ -0,0 +1,369 @@ + + + Computer Model + 0.0.5 + computer + http://example.com/ns/computer + http://example.com/ns/computer + + + Vendor Information + Information about a vendor of a computer part. + + Vendor Identifier + An identifier for classifying a unique computer parts vendor. + + + Vendor Reference + Instead of an identifier, a reference to another vendor by its @id. + + + + Vendor Name + The registered company name of the vendor. + + + Vendor Address + The physical address of an office location for the vendor. + + + Vendor Website + A public website made by the vendor documenting their parts as used in the computer. + + + + + + + + + + Vendor Index by ID + + + + Vendor Reference resolves + + + + + + Product Name + The product name from the vendor of the computer part. + + + Computer Assembly + A container object for a computer, its parts, and its sub-parts. + computer + + + Computer Identifier + An identifier for classifying a unique make and model of computer. + + + + Build Date and Time + The date and time the computer build was completed. + + + + + + Motherboard Assembly + A container object for a motherboard in a computer and its sub-parts. + + + + + Motherboard Type + The type motherboard layout, at, atx, mini-itx or an alternative. + + + Advanced Technology Form Factor + Advanced Technology Extended Form Factor + Mini Information Technology eXtended Form Factor + + + + + Motherboard Central Processing Unit (CPU) + The model number of the CPU on the motherboard of a computer. + + + + + + CPU Architecture + The Instruction Set Architecture (ISA) of the processor, x86, x86-64, arm, or an alternative. + + + x86 32-bit + x86 64-bit + arm + + + + + CPU Speed + The clock speed of the CPU in megahertz or gigahertz. + + + + + + + + + + Motherboard Advanced Technology Attachment (ATA) Socket + The model number of ATA socket on the motherboard of a computer. There will only be one socket on any motherboard. + + + + Slot number + Must be distinctive among ata-sockets, and must be a value between zero (0) and the total number of slots. + + + + + + + ATA Socket Type + The type of ATA socket on the motherboard , pata (parallel ATA), sata (Serial ATA), or an alternative. + + + Parallel ATA + Serial ATA + + + + + + + + + Motherboard Random Access Memory (RAM) Module(s) + Random access memory hardware installed on the motherboard of a computer. + + + + + + + + Memory Module Size + Size of the memory module in binary, not SI base-10 units, meaning a kilobyte is 1024 bytes, not 1000 bytes. + + + + + + + + Motherboard Expansion Card + The model number of an expansion card connected to the motherboard of a computer. + + + + Socket Slot No + Identifies the expansion card's socket by its slot number. Note this should be a non-negative integer between 0 and the count of sockets, but this is not formally defined except on the target. + + + + + + + Expansion Card Type + The type of expansion card on a motherboard of a computer, such as pci (PCI, e.g. Peripheral Component Interconnect), pcie (PCI Express), or an alternative. + + + Peripheral Component Interconnect + Peripheral Component Interconnect Express + + + + + + + + + + + + + + + + + + + + + + + + + + + + Universal Serial Bus Device + A USB expansion device. + + + + USB Device Universally Unique Identifier + An identifier, based on a type 4 UUID, for the USB device. + + + + + + + + + + + + + + + Unique USB Device UUID + Ensures that each USB device has a unique UUID. + + + + Unique Serial Number + Ensures that any device given a serial number have a distinct number. + + + + CPU model + + + + +

Warn if a model is not provided.

+
+
+ + + +

It is invalid to provide multiple models.

+
+
+ + + + + + + +
+ +
+ + Part Cost + The price paid in the specified currency. + price + + Currency Type + The type of currency. + + + + Remarks + Additional remarks related to the containing computer component. + + + Property + An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair. + prop + + Property Name + A textual label, within a namespace, that uniquely identifies a specific attribute, characteristic, or quality of the property's containing object. + + + Property Universally Unique Identifier + + A unique identifier for a property. + + + Property Namespace + A namespace qualifying the property's name. This allows different organizations to associate distinct semantics with the same name. + +

This value must be an absolute URI that serves as a naming system identifier.

+

When a ns is not provided, its value should be assumed to be http://example.com/ns/computer and the name should be a name defined by this model.

+
+
+ + Property Value + Indicates the value of the attribute, characteristic, or quality. + + + Property Class + A textual label that provides a sub-type or characterization of the + property's name. + +

This can be used to further distinguish or discriminate between the semantics of multiple properties of the same object with the same name and ns, or to group properties into categories.

+

A class can be used in validation rules to express extra constraints over named items of a specific class value. It is available for grouping, but unlike group is not expected specifically to designate any group membership as such.

+
+
+ + Property Group + An identifier for relating distinct sets of properties. + +

Different sets of properties may relate to separate contexts. Declare a group on a property to associate it with one or more other properties in a given context.

+
+
+ + + + + + A label or descriptor that is tied to a sensitivity or classification marking system. An optional class can be used to define the specific marking system used for the associated value. + + + +

A property can be included for any purpose useful to an application or implementation. Typically, properties will be used to sort, filter, select, order, and arrange content objects, to relate objects to one another, or to associate an object to class hierarchies, taxonomies, or external authorities. Thus, the lexical composition of properties may be constrained by external processes to ensure consistency.

+

Property allows for associated remarks that describe why the specific property value was applied to the containing object, or the significance of the value in the context of the containing object.

+
+
+ + + Serial Number + A code for this item only. No spaces are permitted. + + + + + + + Cooling + How the computer cools itself. + + + + + Fan + A fan header for a single fan; at least two fans are required for adequate cooling. + + + Water + A cooling system using water for thermal regulation. + + Whether illuminated + The water system is illuminated for visual effect. + + + + + + + +
diff --git a/src/schema-gen/InspectorXSLT/testing/current/computer_metaschema-inspector.xsl b/src/schema-gen/InspectorXSLT/testing/current/computer_metaschema-inspector.xsl new file mode 100644 index 00000000..4865e3aa --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/current/computer_metaschema-inspector.xsl @@ -0,0 +1,2361 @@ + + + + + + + + + inspected + + full + + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + av.152 + _UE unmatched-element + Unrecognized element { name() }. + + + + + + + + + + + + + + av.180 + _UT unexpected-text + Errant text content. + + + + + + + av.193 + _UA unmatched-attribute + Unrecognized attribute @{ name() } on element { name(..) }. + + + + + + + + + + exists(.) + + __U uncategorized + * + [info] + ERROR + + + + + + + + + + + + + + + + + + [info] + + + + + + + + + /{ name() } + + + + + /{ name() }[{ mx:element-position(.)[count($kin) gt 1] }] + + + + /@{ name() } + + + + + [{ count(preceding-sibling::text()|.) }] + /text(){ (count($kin)[. gt 1]) ! $place } + + + + + [{ count(preceding-sibling::comment()|.) }] + /text(){ (count($kin)[. gt 1]) ! $place } + + + + + [{ count(preceding-sibling::processing-instruction()|.) + }] + /text(){ (count($kin)[. gt 1]) ! $place } + + + + + + + + + + + { $as } + { $as }s + + + + + + + + + + + + + + + + + + + + + + + + + + + + + File { replace(@src,'.*/','') } has { $error-count } { + mx:pluralize($error-count,'error')}. + File { replace(@src,'.*/','') } has { $report-count } { + mx:pluralize($report-count,'issue') } reported including { $error-count } { + mx:pluralize($error-count,'error')}. + + + + + + + + + + File { replace(@src,'.*/','') } is reported VALID, no issues ... + + + + + + + + + + + + + + + + + + + + + + + + + { (@level,'ERROR')[1] } [CLASS) { @class } ][PATH) { @xpath } ][REPORT) { + string(.) }] + + + + + + + + + + + + { $validating-filename } - { $checked } - { mx:metaschema/@shortname } validation + + + + + + +

{ $checked } Validating { $validating-filename } - { mx:metaschema } - found { + 'IN'[not($reported-valid)] }VALID

+ + +

+ { $validating-filename } contains { @elements} { + mx:pluralize(@elements/number(),'element') } and { @attributes } { + mx:pluralize(@attributes/number(),'attribute') }.

+ + +
+ +
+
+
+ + +
+ + + + + + +
+

{ count(.//mx:report) } { mx:pluralize(count(.//mx:report),'issue') } reported.

+

+ + 💥 + +

+
+
+ +
+

Good news - nothing to report - the instance is valid. 🚀 +

+
+
+ + + + +
+ + + +

{ @class }{ @level[not(.='ERROR')] ! (' ' || .) }

+
    + +
  • Rule ID: { . } +
  • +
    +
  • test: { @test } +
  • + +
  • matching: { @matching } +
  • +
    +
  • XPath: { @xpath } +
  • +
+
+
+ + + + + + + + + + + + + + + + + { codepoints-to-string(10) } + + + + + + + { $lf } + + + + { $lf2 }--- + + + + # + + + + + { $lf2 }# + + + + + { $lf2 }## + + + + + { $lf2 }### + + + + + { $lf2 } + + + + + + + + + { $lf }- + + + + ** + + ** + + + * + + * + + + ` + + ` + + + Computer Model + + + + + + + + + + + + + + + + + + + gix.670 + + computer/(usb-device) + UNIQ uniqueness-violation + not(count(mx:key-matches-among-items(.,$selected,'UNQ_5',((@uuid)),$within))=1) + + With respect to its assigned (@uuid), this {name(.)} instance of computer/(usb-device) is expected to be unique within its {$within/name(.)}. {count(mx:key-matches-among-items(.,$selected,'UNQ_5',((@uuid)),$within))} items are found with the value {string-join(((@uuid)),',')}. + + + + + + + + + + + gix.670 + + computer/(descendant::*[exists(@serial-number)]) + UNIQ uniqueness-violation + not(count(mx:key-matches-among-items(.,$selected,'UNQ_6',((@serial-number)),$within))=1) + + With respect to its assigned (@serial-number), this {name(.)} instance of computer/(descendant::*[exists(@serial-number)]) is expected to be unique within its {$within/name(.)}. {count(mx:key-matches-among-items(.,$selected,'UNQ_6',((@serial-number)),$within))} items are found with the value {string-join(((@serial-number)),',')}. + + + + + + + gix.502 + + computer/(.//prop[not(@ns) or @ns=('http://example.com/ns/computer')]/@name) + AVCV value-not-allowed + not(.=('model')) + + Value { string(.) }{ .[not(string(.))] ! ' (empty)' } does not appear among permissible (enumerated) values for this { name() }: model. + + + + + + + gix.589 + + computer + HCCV cardinality-violation + not(count(.//prop[not(@ns) or @ns=('http://example.com/ns/computer')]) ge 1 and true()) + + Counting .//prop[not(@ns) or @ns=('http://example.com/ns/computer')] under computer finds {count(.//prop[not(@ns) or @ns=('http://example.com/ns/computer')])} - expecting at least 1. + + + + + + gix.589 + + computer + HCCV cardinality-violation + not(true() and count(.//prop[not(@ns) or @ns=('http://example.com/ns/computer')]) le 1) + + Counting .//prop[not(@ns) or @ns=('http://example.com/ns/computer')] under computer finds {count(.//prop[not(@ns) or @ns=('http://example.com/ns/computer')])} - expecting no more than 1. + + + + + + + + + + gix.621 + + computer/(//a) + NXHK index-lookup-fail + not(exists(mx:key-matches-among-items(.,$selected,'NDX_internal-links',(@href)[matches(.,'^#(.+)$')] ! replace(.,'^#(.+)$','$1'),$within))) + + With respect to its assigned index value, this {name(.)} is expected to correspond within its {$within/name(.)} to a value listed under index internal-links. This index has no entry under the key value {string-join(((@href)[matches(.,'^#(.+)$')] ! replace(.,'^#(.+)$','$1')),',')}. + + + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::vendor) gt 1 + + Element vendor appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::type | preceding-sibling::cpu | preceding-sibling::ata-socket | preceding-sibling::memory | preceding-sibling::cooling | preceding-sibling::expansion-card) + + Element vendor is unexpected following type, cpu, ata-socket, memory, cooling, or expansion-card. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::vendor) gt 1 + + Element vendor appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::product-name | preceding-sibling::cost | preceding-sibling::architecture | preceding-sibling::speed | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element vendor is unexpected following product-name, cost, architecture, speed, prop, or remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::prop) gt 1 + + Element prop appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element prop is unexpected following remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::vendor) gt 1 + + Element vendor appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::product-name | preceding-sibling::cost | preceding-sibling::type | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element vendor is unexpected following product-name, cost, type, prop, or remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::prop) gt 1 + + Element prop appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element prop is unexpected following remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::vendor) gt 1 + + Element vendor appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::product-name | preceding-sibling::cost | preceding-sibling::byte-size | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element vendor is unexpected following product-name, cost, byte-size, prop, or remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::prop) gt 1 + + Element prop appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element prop is unexpected following remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::cooling) gt 1 + + Element cooling appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::expansion-card) + + Element cooling is unexpected following expansion-card. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::vendor) gt 1 + + Element vendor appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::product-name | preceding-sibling::cost | preceding-sibling::type | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element vendor is unexpected following product-name, cost, type, prop, or remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::prop) gt 1 + + Element prop appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element prop is unexpected following remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::vendor) gt 1 + + Element vendor appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::product-name | preceding-sibling::cost | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element vendor is unexpected following product-name, cost, prop, or remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::prop) gt 1 + + Element prop appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element prop is unexpected following remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::prop) gt 1 + + Element prop appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element prop is unexpected following remarks. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::motherboard) gt 1 + + Element motherboard appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::usb-device | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element motherboard is unexpected following usb-device, prop, or remarks. + + + + + + + gix.564 + + /computer/motherboard/(ata-socket/@slot-no) + XPKT expectation-violation + not(. = (0 to count(../../ata-socket))) + + Expression result for /computer/motherboard/(ata-socket/@slot-no) does not conform to expectation . = (0 to count(../../ata-socket)). + + + + + + + + + + gix.670 + + /computer/motherboard/(ata-socket) + UNIQ uniqueness-violation + not(count(mx:key-matches-among-items(.,$selected,'UNQ_3',((@slot-no)),$within))=1) + + With respect to its assigned (@slot-no), this {name(.)} instance of /computer/motherboard/(ata-socket) is expected to be unique within its {$within/name(.)}. {count(mx:key-matches-among-items(.,$selected,'UNQ_3',((@slot-no)),$within))} items are found with the value {string-join(((@slot-no)),',')}. + + + + + + + + + + + gix.621 + + /computer/motherboard/(expansion-card) + NXHK index-lookup-fail + not(exists(mx:key-matches-among-items(.,$selected,'NDX_socket-by-slot',(@socket-no),$within))) + + With respect to its assigned index value, this {name(.)} is expected to correspond within its {$within/name(.)} to a value listed under index socket-by-slot. This index has no entry under the key value {string-join(((@socket-no)),',')}. + + + + + + + gix.589 + + /computer/motherboard + HCCV cardinality-violation + not(count(memory) ge 2 and count(memory) le 12) + + Counting memory under /computer/motherboard finds {count(memory)} - expecting at least 2, no more than 12. + + + + + + gix.564 + + /computer/motherboard + XPKT expectation-violation + not(not(count(child::memory) mod 2)) + + Expression result for /computer/motherboard does not conform to expectation not(count(child::memory) mod 2). + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::cpu) gt 1 + + Element cpu appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::ata-socket | preceding-sibling::memory | preceding-sibling::cooling | preceding-sibling::expansion-card) + + Element cpu is unexpected following ata-socket, memory, cooling, or expansion-card. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::ata-socket) gt 8 + + Element ata-socket appears too many times: 8 maximum are permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::memory | preceding-sibling::cooling | preceding-sibling::expansion-card) + + Element ata-socket is unexpected following memory, cooling, or expansion-card. + + + + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::cooling | preceding-sibling::expansion-card) + + Element memory is unexpected following cooling or expansion-card. + + + + + + + + + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element usb-device is unexpected following prop or remarks. + + + + + + + + gix.336 + EATI element-appears-too-infrequently + empty(following-sibling::fan) and (count(. | preceding-sibling::fan) lt 2) + + Element fan appears too few times: 2 minimum are required. + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::fan) gt 12 + + Element fan appears too many times: 12 maximum are permitted. + + + gix.362 + empty(preceding-sibling::fan) and exists(../(water)) + + VEXC violates-exclusive-choice + Element fan is unexpected along with water. + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::water) gt 1 + + Element water appears too many times: 1 maximum is permitted. + + + gix.362 + empty(preceding-sibling::water) and exists(../(fan)) + + VEXC violates-exclusive-choice + Element water is unexpected along with fan. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::product-name) gt 1 + + Element product-name appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::cost | preceding-sibling::architecture | preceding-sibling::speed | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element product-name is unexpected following cost, architecture, speed, prop, or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::cost) gt 1 + + Element cost appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::architecture | preceding-sibling::speed | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element cost is unexpected following architecture, speed, prop, or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::product-name) gt 1 + + Element product-name appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::cost | preceding-sibling::type | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element product-name is unexpected following cost, type, prop, or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::cost) gt 1 + + Element cost appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::type | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element cost is unexpected following type, prop, or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::product-name) gt 1 + + Element product-name appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::cost | preceding-sibling::byte-size | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element product-name is unexpected following cost, byte-size, prop, or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::cost) gt 1 + + Element cost appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::byte-size | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element cost is unexpected following byte-size, prop, or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::product-name) gt 1 + + Element product-name appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::cost | preceding-sibling::type | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element product-name is unexpected following cost, type, prop, or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::cost) gt 1 + + Element cost appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::type | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element cost is unexpected following type, prop, or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::product-name) gt 1 + + Element product-name appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::cost | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element product-name is unexpected following cost, prop, or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::cost) gt 1 + + Element cost appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element cost is unexpected following prop or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::remarks) gt 1 + + Element remarks appears too many times: 1 maximum is permitted. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::name) gt 1 + + Element name appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::address | preceding-sibling::website) + + Element name is unexpected following address or website. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::address) gt 1 + + Element address appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::website) + + Element address is unexpected following website. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::website) gt 1 + + Element website appears too many times: 1 maximum is permitted. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::build-date) gt 1 + + Element build-date appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::motherboard | preceding-sibling::usb-device | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element build-date is unexpected following motherboard, usb-device, prop, or remarks. + + + + + + + gix.564 + + /computer/build-date + XPKT expectation-violation + not(not(. castable as xs:dateTime) or not(xs:dateTime('1970-01-01T00:00:00-05:00') > xs:dateTime(.))) + + Expression result for /computer/build-date does not conform to expectation not(. castable as xs:dateTime) or not(xs:dateTime('1970-01-01T00:00:00-05:00') > xs:dateTime(.)). + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::type) gt 1 + + Element type appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::cpu | preceding-sibling::ata-socket | preceding-sibling::memory | preceding-sibling::cooling | preceding-sibling::expansion-card) + + Element type is unexpected following cpu, ata-socket, memory, cooling, or expansion-card. + + + + + + + gix.502 + + computer/motherboard/type + AVCV value-not-allowed + not(.=('at','atx','mini-itx')) + + Value { string(.) }{ .[not(string(.))] ! ' (empty)' } does not appear among permissible (enumerated) values for this { name() }: at|atx|mini-itx. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::architecture) gt 1 + + Element architecture appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::speed | preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element architecture is unexpected following speed, prop, or remarks. + + + + + + + gix.502 + + motherboard/cpu/architecture + AVCV value-not-allowed + not(.=('x86','x86-64','arm')) + + Value { string(.) }{ .[not(string(.))] ! ' (empty)' } does not appear among permissible (enumerated) values for this { name() }: x86|x86-64|arm. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::speed) gt 1 + + Element speed appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element speed is unexpected following prop or remarks. + + + + + + + gix.536 + + motherboard/cpu/speed + MRCV regex-match-fail + not(matches(., '^\d+(?:\.\d+)?(?:MHz|GHz)$')) + + + { string(.) }{ string(.)[not(.)] ! ' (empty)' } does not match the regular expression defined for this { name() }: \d+(?:\.\d+)?(?:MHz|GHz). + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::type) gt 1 + + Element type appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element type is unexpected following prop or remarks. + + + + + + + gix.502 + + motherboard/ata-socket/type + AVCV value-not-allowed + not(.=('pata','sata')) + + Value { string(.) }{ .[not(string(.))] ! ' (empty)' } does not appear among permissible (enumerated) values for this { name() }: pata|sata. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::byte-size) gt 1 + + Element byte-size appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element byte-size is unexpected following prop or remarks. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::type) gt 1 + + Element type appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::prop | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element type is unexpected following prop or remarks. + + + + + + + gix.502 + + motherboard/expansion-card/type + AVCV value-not-allowed + not(.=('pci','pcie')) + + Value { string(.) }{ .[not(string(.))] ! ' (empty)' } does not appear among permissible (enumerated) values for this { name() }: pci|pcie. + + + + + + + + + + + gix.536 + + /computer/@serial-number + MRCV regex-match-fail + not(matches(., '^^\S+$$')) + + + { string(.) }{ string(.)[not(.)] ! ' (empty)' } does not match the regular expression defined for this { name() }: ^\S+$. + + + + + + + + + + gix.536 + + computer/motherboard/@serial-number + MRCV regex-match-fail + not(matches(., '^^\S+$$')) + + + { string(.) }{ string(.)[not(.)] ! ' (empty)' } does not match the regular expression defined for this { name() }: ^\S+$. + + + + + + + + + + gix.536 + + motherboard/ata-socket/@serial-number + MRCV regex-match-fail + not(matches(., '^^\S+$$')) + + + { string(.) }{ string(.)[not(.)] ! ' (empty)' } does not match the regular expression defined for this { name() }: ^\S+$. + + + + + + + + + + gix.536 + + motherboard/memory/@serial-number + MRCV regex-match-fail + not(matches(., '^^\S+$$')) + + + { string(.) }{ string(.)[not(.)] ! ' (empty)' } does not match the regular expression defined for this { name() }: ^\S+$. + + + + + + + + + + gix.536 + + motherboard/expansion-card/@serial-number + MRCV regex-match-fail + not(matches(., '^^\S+$$')) + + + { string(.) }{ string(.)[not(.)] ! ' (empty)' } does not match the regular expression defined for this { name() }: ^\S+$. + + + + + + + + + + gix.536 + + motherboard/cooling/@serial-number + MRCV regex-match-fail + not(matches(., '^^\S+$$')) + + + { string(.) }{ string(.)[not(.)] ! ' (empty)' } does not match the regular expression defined for this { name() }: ^\S+$. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gix.108 + EOOP element-out-of-place + Element { name() } is not permitted here. + + + + + gix.117 + AOOP attribute-out-of-place + Attribute @{ name() } is not permitted here. + + + + + + + + gix.445 + MRQC missing-required-contents + empty(name) + + Element { name() } requires element name. + + + gix.445 + MRQC missing-required-contents + empty(address) + + Element { name() } requires element address. + + + gix.445 + MRQC missing-required-contents + empty(website) + + Element { name() } requires element website. + + + + + + + + + + + + + + + + + + + + + + + gix.748 + MRQA missing-required-attribute + empty(@id) + + Element { name() } requires attribute @id. + + + + + + + + + + + gix.445 + MRQC missing-required-contents + empty(type) + + Element { name() } requires element type. + + + gix.445 + MRQC missing-required-contents + empty(memory) + + Element { name() } requires element memory. + + + + + + + + gix.445 + MRQC missing-required-contents + empty(product-name) + + Element { name() } requires element product-name. + + + gix.445 + MRQC missing-required-contents + empty(architecture) + + Element { name() } requires element architecture. + + + gix.445 + MRQC missing-required-contents + empty(speed) + + Element { name() } requires element speed. + + + + + + + + + + + gix.748 + MRQA missing-required-attribute + empty(@slot-no) + + Element { name() } requires attribute @slot-no. + + + gix.445 + MRQC missing-required-contents + empty(product-name) + + Element { name() } requires element product-name. + + + gix.445 + MRQC missing-required-contents + empty(type) + + Element { name() } requires element type. + + + + + + + + + + + gix.445 + MRQC missing-required-contents + empty(product-name) + + Element { name() } requires element product-name. + + + gix.445 + MRQC missing-required-contents + empty(byte-size) + + Element { name() } requires element byte-size. + + + + + + + + gix.748 + MRQA missing-required-attribute + empty(@socket-no) + + Element { name() } requires attribute @socket-no. + + + gix.445 + MRQC missing-required-contents + empty(product-name) + + Element { name() } requires element product-name. + + + gix.445 + MRQC missing-required-contents + empty(type) + + Element { name() } requires element type. + + + + + + + + + + + gix.445 + MRQC missing-required-contents + empty(product-name) + + Element { name() } requires element product-name. + + + + + + + + gix.748 + MRQA missing-required-attribute + empty(@currency) + + Element { name() } requires attribute @currency. + + + + + + + + + + + + gix.748 + MRQA missing-required-attribute + empty(@name) + + Element { name() } requires attribute @name. + + + gix.748 + MRQA missing-required-attribute + empty(@value) + + Element { name() } requires attribute @value. + + + + + + + + + + + + + + + + + + + + + + + + + + gix.445 + MRQC missing-required-contents + empty(fan|water) + + Element { name() } requires element fan|water. + + + + + + + + + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:string and matches(.,'^\S(.*\S)?$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to string datatype. + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:anyURI and matches(.,'^[a-zA-Z][a-zA-Z0-9+\-.]+:.*\S$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to uri datatype. + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:dateTime and matches(.,'^(((2000|2400|2800|(19|2[0-9](0[48]|[2468][048]|[13579][26])))-02-29)|(((19|2[0-9])[0-9]{2})-02-(0[1-9]|1[0-9]|2[0-8]))|(((19|2[0-9])[0-9]{2})-(0[13578]|10|12)-(0[1-9]|[12][0-9]|3[01]))|(((19|2[0-9])[0-9]{2})-(0[469]|11)-(0[1-9]|[12][0-9]|30)))T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|(-((0[0-9]|1[0-2]):00|0[39]:30)|\+((0[0-9]|1[0-4]):00|(0[34569]|10):30|(0[58]|12):45)))$') and matches(.,'^(((2000|2400|2800|(19|2[0-9](0[48]|[2468][048]|[13579][26])))-02-29)|(((19|2[0-9])[0-9]{2})-02-(0[1-9]|1[0-9]|2[0-8]))|(((19|2[0-9])[0-9]{2})-(0[13578]|10|12)-(0[1-9]|[12][0-9]|3[01]))|(((19|2[0-9])[0-9]{2})-(0[469]|11)-(0[1-9]|[12][0-9]|30)))T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|(-((0[0-9]|1[0-2]):00|0[39]:30)|\+((0[0-9]|1[0-4]):00|(0[34569]|10):30|(0[58]|12):45)))?$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to date-time-with-timezone datatype. + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:nonNegativeInteger and matches(.,'^\S(.*\S)?$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to non-negative-integer datatype. + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:positiveInteger and matches(.,'^\S(.*\S)?$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to positive-integer datatype. + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:string and matches(.,'^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[45][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$') and matches(.,'^\S(.*\S)?$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to uuid datatype. + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:decimal and matches(.,'^\S(.*\S)?$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to decimal datatype. + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:string and matches(.,'^(\p{L}|_)(\p{L}|\p{N}|[.\-_])*$') and matches(.,'^\S(.*\S)?$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to token datatype. + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:boolean and matches(.,'^true|1|false|0$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to boolean datatype. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/schema-gen/InspectorXSLT/testing/current/computer_metaschema-schema.xsd b/src/schema-gen/InspectorXSLT/testing/current/computer_metaschema-schema.xsd new file mode 100644 index 00000000..4fa290d5 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/current/computer_metaschema-schema.xsd @@ -0,0 +1,952 @@ + + + + + Computer Model + 0.0.5 + computer + computer + + + + + + Vendor Information + Information about a vendor of a computer part. + + + Vendor Information: Information about a vendor of a computer part. + + + + + + + Vendor Name + The registered company name of the vendor. + + + Vendor Name: The registered company name of the vendor. + + + + + + + + + Vendor Address + The physical address of an office location for the vendor. + + + Vendor Address: The physical address of an office location for the vendor. + + + + + + + + + Vendor Website + A public website made by the vendor documenting their parts as used in the computer. + + + Vendor Website: A public website made by the vendor documenting their parts as used in the computer. + + + + + + + + + Vendor Identifier + An identifier for classifying a unique computer parts vendor. + + + Vendor Identifier: An identifier for classifying a unique computer parts vendor. + + + + + + + Product Name + The product name from the vendor of the computer part. + + + Product Name: The product name from the vendor of the computer part. + + + + + + + + Computer Assembly + A container object for a computer, its parts, and its sub-parts. + + + Computer Assembly: A container object for a computer, its parts, and its sub-parts. + + + + + + + Build Date and Time + The date and time the computer build was completed. + + + Build Date and Time: The date and time the computer build was completed. + + + + + + + + + Motherboard Assembly + A container object for a motherboard in a computer and its sub-parts. + + + Motherboard Assembly: A container object for a motherboard in a computer and its sub-parts. + + + + + + + + Motherboard Type + The type motherboard layout, at, atx, mini-itx or an alternative. + + + Motherboard Type: The type motherboard layout, at, atx, mini-itx or an alternative. + + + + + + + + + Motherboard Central Processing Unit (CPU) + The model number of the CPU on the motherboard of a computer. + + + Motherboard Central Processing Unit (CPU): The model number of the CPU on the motherboard of a computer. + + + + + + + + + + CPU Architecture + The Instruction Set Architecture (ISA) of the processor, x86, x86-64, arm, or an alternative. + + + CPU Architecture: The Instruction Set Architecture (ISA) of the processor, x86, x86-64, arm, or an alternative. + + + + + + + + + CPU Speed + The clock speed of the CPU in megahertz or gigahertz. + + + CPU Speed: The clock speed of the CPU in megahertz or gigahertz. + + + + + + + + + + + + + + Motherboard Advanced Technology Attachment (ATA) Socket + The model number of ATA socket on the motherboard of a computer. There will only be one socket on any motherboard. + + + Motherboard Advanced Technology Attachment (ATA) Socket: The model number of ATA socket on the motherboard of a computer. There will only be one socket on any motherboard. + + + + + + + + + + ATA Socket Type + The type of ATA socket on the motherboard , pata (parallel ATA), sata (Serial ATA), or an alternative. + + + ATA Socket Type: The type of ATA socket on the motherboard , pata (parallel ATA), sata (Serial ATA), or an alternative. + + + + + + + + + + + Serial Number + A code for this item only. No spaces are permitted. + + + Serial Number: A code for this item only. No spaces are permitted. + + + + + + Slot number + Must be distinctive among ata-sockets, and must be a value between zero (0) and the total number of slots. + + + Slot number: Must be distinctive among ata-sockets, and must be a value between zero (0) and the total number of slots. + + + + + + + + + Motherboard Random Access Memory (RAM) Module(s) + Random access memory hardware installed on the motherboard of a computer. + + + Motherboard Random Access Memory (RAM) Module(s): Random access memory hardware installed on the motherboard of a computer. + + + + + + + + + + Memory Module Size + Size of the memory module in binary, not SI base-10 units, meaning a kilobyte is 1024 bytes, not 1000 bytes. + + + Memory Module Size: Size of the memory module in binary, not SI base-10 units, meaning a kilobyte is 1024 bytes, not 1000 bytes. + + + + + + + + + + + Serial Number + A code for this item only. No spaces are permitted. + + + Serial Number: A code for this item only. No spaces are permitted. + + + + + + + + + + Motherboard Expansion Card + The model number of an expansion card connected to the motherboard of a computer. + + + Motherboard Expansion Card: The model number of an expansion card connected to the motherboard of a computer. + + + + + + + + + + Expansion Card Type + The type of expansion card on a motherboard of a computer, such as pci (PCI, e.g. Peripheral Component Interconnect), pcie (PCI Express), or an alternative. + + + Expansion Card Type: The type of expansion card on a motherboard of a computer, such as pci (PCI, e.g. Peripheral Component Interconnect), pcie (PCI Express), or an alternative. + + + + + + + + + + + Serial Number + A code for this item only. No spaces are permitted. + + + Serial Number: A code for this item only. No spaces are permitted. + + + + + + Socket Slot No + Identifies the expansion card's socket by its slot number. Note this should be a non-negative integer between 0 and the count of sockets, but this is not formally defined except on the target. + + + Socket Slot No: Identifies the expansion card's socket by its slot number. Note this should be a non-negative integer between 0 and the count of sockets, but this is not formally defined except on the target. + + + + + + + + + Serial Number + A code for this item only. No spaces are permitted. + + + Serial Number: A code for this item only. No spaces are permitted. + + + + + + + + + Universal Serial Bus Device + A USB expansion device. + + + Universal Serial Bus Device: A USB expansion device. + + + + + + + + + + + + USB Device Universally Unique Identifier + An identifier, based on a type 4 UUID, for the USB device. + + + USB Device Universally Unique Identifier: An identifier, based on a type 4 UUID, for the USB device. + + + + + + + + + + + Serial Number + A code for this item only. No spaces are permitted. + + + Serial Number: A code for this item only. No spaces are permitted. + + + + + + Computer Identifier + An identifier for classifying a unique make and model of computer. + + + Computer Identifier: An identifier for classifying a unique make and model of computer. + + + + + + + Part Cost + The price paid in the specified currency. + + + Part Cost: The price paid in the specified currency. + + + + + + + Currency Type + The type of currency. + + + Currency Type: The type of currency. + + + + + + + + + Remarks + Additional remarks related to the containing computer component. + + + Remarks: Additional remarks related to the containing computer component. + + + + + + + + + Property + An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair. + + + Property: An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair. + + + + + + Remarks + Additional remarks related to the containing computer component. + + + Remarks: Additional remarks related to the containing computer component. + + + + + + + + + + Property Name + A textual label, within a namespace, that uniquely identifies a specific attribute, characteristic, or quality of the property's containing object. + + + Property Name: A textual label, within a namespace, that uniquely identifies a specific attribute, characteristic, or quality of the property's containing object. + + + + + + Property Universally Unique Identifier + A unique identifier for a property. + + + Property Universally Unique Identifier: A unique identifier for a property. + + + + + + Property Namespace + A namespace qualifying the property's name. This allows different organizations to associate distinct semantics with the same name. + + + Property Namespace: A namespace qualifying the property's name. This allows different organizations to associate distinct semantics with the same name. + + + + + + Property Value + Indicates the value of the attribute, characteristic, or quality. + + + Property Value: Indicates the value of the attribute, characteristic, or quality. + + + + + + Property Class + A textual label that provides a sub-type or characterization of the property's name. + + + Property Class: A textual label that provides a sub-type or characterization of the property's name. + + + + + + Property Group + An identifier for relating distinct sets of properties. + + + Property Group: An identifier for relating distinct sets of properties. + + + + + + + Cooling + How the computer cools itself. + + + Cooling: How the computer cools itself. + + + + + + + + Fan + A fan header for a single fan; at least two fans are required for adequate cooling. + + + Fan: A fan header for a single fan; at least two fans are required for adequate cooling. + + + + + + + + Water + A cooling system using water for thermal regulation. + + + Water: A cooling system using water for thermal regulation. + + + + + Whether illuminated + The water system is illuminated for visual effect. + + + Whether illuminated: The water system is illuminated for visual effect. + + + + + + + + + + Serial Number + A code for this item only. No spaces are permitted. + + + Serial Number: A code for this item only. No spaces are permitted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The content model is the same as inlineMarkupType, but line endings need + to be preserved, since this is pre-formatted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + An insert can be used to identify a placeholder for dynamically inserting text related to a specific object, which is referenced by the object's identifier using an id-ref. This insert mechanism allows the selection of which text value from the object to dynamically include based on the application's display requirements. + + + + The type of object to include from (e.g., parameter, control, component, role, etc.) + + + + + The identity of the object to insert a value for. The identity will be selected from the index of objects of the specified type. The specific value to include is based on the application's display requirements, which will likely use a specific data element associated with the type (e.g., title, identifier, value, etc.) that is appropriate for the application. + + + + + + A binary value that is either: true (or 1) or false (or 0). + + + + + + + + A string representing a point in time with an optional timezone. + + + + + + + + A string representing a point in time with a required timezone. + + + + + + + + A real number expressed using a whole and optional fractional part + separated by a period. + + + + + This pattern ensures that leading and trailing whitespace is + disallowed. This helps to even the user experience between implementations + related to whitespace. + + + + + + + An integer value that is equal to or greater than 0. + + + + + This pattern ensures that leading and trailing whitespace is + disallowed. This helps to even the user experience between implementations + related to whitespace. + + + + + + + An integer value that is greater than 0. + + + + + This pattern ensures that leading and trailing whitespace is + disallowed. This helps to even the user experience between implementations + related to whitespace. + + + + + + + A non-empty string of Unicode characters with leading and trailing whitespace + disallowed. Whitespace is: U+9, U+10, U+32 or [ \n\t]+ + + + + The 'string' datatype restricts the XSD type by prohibiting leading + and trailing whitespace, and something (not only whitespace) is required. + + + + + This pattern ensures that leading and trailing whitespace is + disallowed. This helps to even the user experience between implementations + related to whitespace. + + + + + + + + A non-empty, non-colonized name as defined by XML Schema Part 2: Datatypes + Second Edition (https://www.w3.org/TR/xmlschema11-2/#NCName), with leading and trailing + whitespace disallowed. + + + + + + A single token may not contain whitespace. + + + + + + + + A universal resource identifier (URI) formatted according to RFC3986. + + + + + Requires a scheme with colon per RFC 3986. + + + + + + + A type 4 ('random' or 'pseudorandom') or type 5 UUID per RFC + 4122. + + + + + A sequence of 8-4-4-4-12 hex digits, with extra + constraints in the 13th and 17-18th places for version 4 and 5 + + + + + + diff --git a/src/schema-gen/InspectorXSLT/testing/current/tiny_metaschema-inspector.xsl b/src/schema-gen/InspectorXSLT/testing/current/tiny_metaschema-inspector.xsl new file mode 100644 index 00000000..44cb4883 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/current/tiny_metaschema-inspector.xsl @@ -0,0 +1,889 @@ + + + + + + + + + inspected + + full + + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + av.152 + _UE unmatched-element + Unrecognized element { name() }. + + + + + + + + + + + + + + av.180 + _UT unexpected-text + Errant text content. + + + + + + + av.193 + _UA unmatched-attribute + Unrecognized attribute @{ name() } on element { name(..) }. + + + + + + + + + + exists(.) + + __U uncategorized + * + [info] + ERROR + + + + + + + + + + + + + + + + + + [info] + + + + + + + + + /{ name() } + + + + + /{ name() }[{ mx:element-position(.)[count($kin) gt 1] }] + + + + /@{ name() } + + + + + [{ count(preceding-sibling::text()|.) }] + /text(){ (count($kin)[. gt 1]) ! $place } + + + + + [{ count(preceding-sibling::comment()|.) }] + /text(){ (count($kin)[. gt 1]) ! $place } + + + + + [{ count(preceding-sibling::processing-instruction()|.) + }] + /text(){ (count($kin)[. gt 1]) ! $place } + + + + + + + + + + + { $as } + { $as }s + + + + + + + + + + + + + + + + + + + + + + + + + + + + + File { replace(@src,'.*/','') } has { $error-count } { + mx:pluralize($error-count,'error')}. + File { replace(@src,'.*/','') } has { $report-count } { + mx:pluralize($report-count,'issue') } reported including { $error-count } { + mx:pluralize($error-count,'error')}. + + + + + + + + + + File { replace(@src,'.*/','') } is reported VALID, no issues ... + + + + + + + + + + + + + + + + + + + + + + + + + { (@level,'ERROR')[1] } [CLASS) { @class } ][PATH) { @xpath } ][REPORT) { + string(.) }] + + + + + + + + + + + + { $validating-filename } - { $checked } - { mx:metaschema/@shortname } validation + + + + + + +

{ $checked } Validating { $validating-filename } - { mx:metaschema } - found { + 'IN'[not($reported-valid)] }VALID

+ + +

+ { $validating-filename } contains { @elements} { + mx:pluralize(@elements/number(),'element') } and { @attributes } { + mx:pluralize(@attributes/number(),'attribute') }.

+ + +
+ +
+
+
+ + +
+ + + + + + +
+

{ count(.//mx:report) } { mx:pluralize(count(.//mx:report),'issue') } reported.

+

+ + 💥 + +

+
+
+ +
+

Good news - nothing to report - the instance is valid. 🚀 +

+
+
+ + + + +
+ + + +

{ @class }{ @level[not(.='ERROR')] ! (' ' || .) }

+
    + +
  • Rule ID: { . } +
  • +
    +
  • test: { @test } +
  • + +
  • matching: { @matching } +
  • +
    +
  • XPath: { @xpath } +
  • +
+
+
+ + + + + + + + + + + + + + + + + { codepoints-to-string(10) } + + + + + + + { $lf } + + + + { $lf2 }--- + + + + # + + + + + { $lf2 }# + + + + + { $lf2 }## + + + + + { $lf2 }### + + + + + { $lf2 } + + + + + + + + + { $lf }- + + + + ** + + ** + + + * + + * + + + ` + + ` + + + Computer Model + + + + + + + + + + + + + + + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::notes) + + Element part is unexpected following notes/note. + + + + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::note) + + Element part is unexpected following note. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::title) gt 1 + + Element title appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::term | preceding-sibling::part | preceding-sibling::notes | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element title is unexpected following term, stuff, part, or notes/note. + + + + + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::part | preceding-sibling::notes | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element term is unexpected following stuff, part, or notes/note. + + + + + + + + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::title) gt 1 + + Element title appears too many times: 1 maximum is permitted. + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::term | preceding-sibling::part | preceding-sibling::note | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element title is unexpected following term, stuff, part, or note. + + + + + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::part | preceding-sibling::note | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element term is unexpected following stuff, part, or note. + + + + + + + + + gix.347 + EATO element-appears-too-often + count(. | preceding-sibling::note) gt 1 + + Element note appears too many times: 1 maximum is permitted. + + + + + + + + + + + + + + + + + + gix.108 + EOOP element-out-of-place + Element { name() } is not permitted here. + + + + + gix.117 + AOOP attribute-out-of-place + Attribute @{ name() } is not permitted here. + + + + + + + + gix.748 + MRQA missing-required-attribute + empty(@id) + + Element { name() } requires attribute @id. + + + gix.445 + MRQC missing-required-contents + empty(title) + + Element { name() } requires element title. + + + + + + + + + + + + + + gix.748 + MRQA missing-required-attribute + empty(@id) + + Element { name() } requires attribute @id. + + + + + + + + + + + + gix.445 + MRQC missing-required-contents + empty(title) + + Element { name() } requires element title. + + + + + + + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:string and matches(.,'^\S(.*\S)?$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to string datatype. + + + + + VDSX violates-datatype-syntax + + + gix.148 + + + { $class } + not(string(.) castable as xs:string and matches(.,'^(\p{L}|_)(\p{L}|\p{N}|[.\-_])*$') and matches(.,'^\S(.*\S)?$')) + + Value { string(.) } of { if (self::element()) then 'element' else 'attribute' } { self::attribute()/'@' }{ name(.) } does not conform to token datatype. + + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::part | preceding-sibling::notes) + + Element stuff is unexpected following part or notes/note. + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::part | preceding-sibling::note) + + Element stuff is unexpected following part or note. + + + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::term | preceding-sibling::part | preceding-sibling::notes | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element title is unexpected following term, stuff, part, or notes/note. + + + + + gix.390 + EOOO element-out-of-order + exists(preceding-sibling::term | preceding-sibling::part | preceding-sibling::note | preceding-sibling::h1 | preceding-sibling::h2 | preceding-sibling::h3 | preceding-sibling::h4 | preceding-sibling::h5 | preceding-sibling::h6 | preceding-sibling::table | preceding-sibling::img | preceding-sibling::pre | preceding-sibling::hr | preceding-sibling::blockquote | preceding-sibling::ul | preceding-sibling::ol | preceding-sibling::p) + + Element title is unexpected following term, stuff, part, or note. + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/schema-gen/InspectorXSLT/testing/current/tiny_metaschema-schema.xsd b/src/schema-gen/InspectorXSLT/testing/current/tiny_metaschema-schema.xsd new file mode 100644 index 00000000..8abaa3d5 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/current/tiny_metaschema-schema.xsd @@ -0,0 +1,377 @@ + + + + + Computer Model + 0.0.5 + computer + +

Tiny Metaschema

+

A metaschema can be small and yet deep.

+
+ TINY +
+
+ + + + + Tiny Data + A minimally described data set. + + + Tiny Data: A minimally described data set. + + + + + + + + + + + + + Note + Wrapped markup-multiline example. + + + Note: Wrapped markup-multiline example. + + + + + + + + + + + + + Tiny ID + An identifier. + + + Tiny ID: An identifier. + + + + + + + Title + markup-line example. + + + Title: markup-line example. + + + + + + + + + Term + Simple string value example. + + + Term: Simple string value example. + + + + + + + Term identifier + A token identifying this term uniquely within the document. + + + Term identifier: A token identifying this term uniquely within the document. + + + + + + + + + Note + Wrapped markup-multiline example. + + + Note: Wrapped markup-multiline example. + + + + + + + + + Tiny part + A bit of tiny data. + + + Tiny part: A bit of tiny data. + + + + + + + + + + Note + Wrapped markup-multiline example. + + + Note: Wrapped markup-multiline example. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The content model is the same as inlineMarkupType, but line endings need + to be preserved, since this is pre-formatted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + An insert can be used to identify a placeholder for dynamically inserting text related to a specific object, which is referenced by the object's identifier using an id-ref. This insert mechanism allows the selection of which text value from the object to dynamically include based on the application's display requirements. + + + + The type of object to include from (e.g., parameter, control, component, role, etc.) + + + + + The identity of the object to insert a value for. The identity will be selected from the index of objects of the specified type. The specific value to include is based on the application's display requirements, which will likely use a specific data element associated with the type (e.g., title, identifier, value, etc.) that is appropriate for the application. + + + + + + A non-empty string of Unicode characters with leading and trailing whitespace + disallowed. Whitespace is: U+9, U+10, U+32 or [ \n\t]+ + + + + The 'string' datatype restricts the XSD type by prohibiting leading + and trailing whitespace, and something (not only whitespace) is required. + + + + + This pattern ensures that leading and trailing whitespace is + disallowed. This helps to even the user experience between implementations + related to whitespace. + + + + + + + + A non-empty, non-colonized name as defined by XML Schema Part 2: Datatypes + Second Edition (https://www.w3.org/TR/xmlschema11-2/#NCName), with leading and trailing + whitespace disallowed. + + + + + + A single token may not contain whitespace. + + + + + +
diff --git a/src/schema-gen/InspectorXSLT/testing/inspect-computer.sh b/src/schema-gen/InspectorXSLT/testing/inspect-computer.sh new file mode 100644 index 00000000..eedf276b --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/inspect-computer.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +# Fail early if an error occurs +set -Eeuo pipefail + +usage() { + cat <&2 + exit 1 +fi + +[[ -z "${1-}" ]] && { echo "Error: XML_SOURCE not specified"; usage; exit 1; } +XML_SOURCE=$1 + +ADDITIONAL_ARGS=$(shift 1; echo ${*// /\\ }) + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" +POM_FILE="${SCRIPT_DIR}/../../../../support/pom.xml" + +MAIN_CLASS="net.sf.saxon.Transform" # Saxon defined in pom.xml + +mvn \ + -quiet \ + -f "$POM_FILE" \ + exec:java \ + -Dexec.mainClass="$MAIN_CLASS" \ + -Dexec.args="-xsl:${SCRIPT_DIR}/current/computer_inspector.xsl -s:\"$XML_SOURCE\" $ADDITIONAL_ARGS" + +echo diff --git a/src/schema-gen/InspectorXSLT/testing/planning.md b/src/schema-gen/InspectorXSLT/testing/planning.md new file mode 100644 index 00000000..0eca38cc --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/planning.md @@ -0,0 +1,53 @@ +# Planning + +## Testing + +- [ ] [Run CI/CD on forks?]( https://github.com/marketplace/actions/publish-test-results#support-fork-repositories-and-dependabot-branches) +- [ ] If not, then find a graceful way to error on failures, in forks +- [x] Refactor testing in this directory + - [x] smoke-test: is a functional XSLT produced from a valid Metaschema + - [x] unit-test: + - current production tests (build out a little) + - report (mx) format to HTML presentation XSLT + - [x] spec-test: current functional tests + +## Inspector XSLT + +- [ ] Revisit allowed-values semantics? + - [ ] isolate an example (OSCAL?) + - [ ] XSpec a retrieval function returning (rule/value)* + - [ ] check back, anything missed? +- [ ] Address OSCAL functional gaps + - [ ] OSCAL implementation in oscal-xslt repository +- [ ] More assertively test all constraints +- [ ] More assertively test markup-line and markup-multiline +- [ ] Test out other aspects + - [ ] interesting assembly/field settings, use-name etc + - [ ] XSpec MX to HTML to Markdown? functions? + - [ ] Build out TINY to include constraints on insert (note-ref and term-ref) +- [ ] Review specs with eye to contributions +- [ ] CSX version + - [ ] CI/CD support for deployment from updated metaschema sources? +- [ ] Release plans and considerations +- [ ] Review opportunities for unit tests: reuse / pubs / pool + +### Test coverage + +Working edges: +- Wrapped and unwrapped markup-multiline +- grouped and ungrouped elements and their siblings +- absolute target paths +- broken paths (graceful prevention?) +- INFO and WARNING level tests +- key scoping for index and is-unique + +Use constraint rule IDs to wrangle and cross-link constraints with tests + +markup line and markup-multiline validation + +- unknown elements +- elements out of place +- text out of place +- weird edge cases e.g. in-xml +- extract these from XSD sources? +- diff --git a/src/schema-gen/InspectorXSLT/testing/readme.md b/src/schema-gen/InspectorXSLT/testing/readme.md new file mode 100644 index 00000000..0d2ca505 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/readme.md @@ -0,0 +1,35 @@ +# Testing Metaschema XSLT Inspector XSLT + +See the [TESTING](../TESTING.md) docs for Inspector XSLT for explanation of how to test the application using these resources. + +## Apologies to the XML-averse (for now) + +Keep in mind when considering testing that Inspector XSLT currently only supports XML-based formats defined by a metaschema. Your JSON can be inspected only if you convert it to XML first - a conversion that is dependable only if the data was already valid to begin with. + +(Running a metaschema-configured conversion, comparing results, and running a conversion again - even apart from applying the Inspector - is however quite a good way in general of determining metaschema-validity of non-XML formats based on Metaschema.) + +## If you have a metaschema that you wish to use + +Any valid and correct Metaschema module can be used to produce an Inspector for the XML format defined by that metaschema. Use the included script to produce your Inspector XSLT, or run the generator pipeline directly, not skipping composition, (Even a self-containted schema module in one file needs to be composed to link up definitions with their uses.) + +In this subdirectory, two models (at time of writing) are used in harnesses for testing Metaschema-based XSLT generation (transpiling): `computer_metaschema.xml` and `tiny_metaschema.xml`. Together these are able to represent a broad range (ultimateley, the broadest range possible) of metaschema-based declarative functionality in modeling and constraint definition. At present they are also useful examples of small metaschema-based applications. + +This means the developer of any metaschema should be able to copy handling found here, especially for `computer_metaschema.xml`, such as scripts for [refreshing an InspectorXSLT for testing](refresh-computer-inspector.sh), or [simply to apply an InspectorXSLT](inspect-computer.sh) to an XML document nominated at the command line. + +See the [InspectorXSLT readme](../readme.md) for more information. Additionally, please consider reporting what you learn and letting project developers know of your needs as a Metaschema consumer and implementor. + +## Working with the trial (model) metaschemas + +`computer_metaschema.xml` has been provided with some outlandish rules and constraints, enabling it as a testbed for the application of constraints to arbitrary metaschema-defined data (specifically XML for this application). + +Some [known-valid](valid/) and [known-invalid](invalid/) instances are also provided, serving as examples and out-of-line tests. + +Additionally, `tiny_metaschema.xml` is a small metaschema made specifically for trying and testing the markup datatypes. + +### XSpec demonstrating correctness of the Inspector + +An Inspector can be generated from a metaschema such as `computer_model.xml` and tested against known inputs to demonstrate that the tests performed by the Inspector bring the correct results. + +Exercising these tests, a number of XSpec files in this folder calling `current/computer_metaschema-inspector.xsl` should all complete successfully and report "all green" -- no warnings, no errors, no unexpected 'pending' sections. + +See the [TESTING](../TESTING.md) docs for more information. diff --git a/src/schema-gen/InspectorXSLT/testing/refresh-computer-inspector-saxon.sh b/src/schema-gen/InspectorXSLT/testing/refresh-computer-inspector-saxon.sh new file mode 100644 index 00000000..0331ed90 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/refresh-computer-inspector-saxon.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +# This script shows how to use Saxon with only a Maven dependency. +# Unlike other scripts in this folder it does not rely on an external (bash scripting) dependency +# Another difference is that it bypasses the XSLT-checking, so GIGO - this can be useful (for producing an XSLT for debugging) +# Maven is required on your system PATH. + +# Fail early if an error occurs +set -Eeuo pipefail + +usage() { + cat <&2 + exit 1 +fi + +METASCHEMA_SOURCE=computer_metaschema.xml + +XSLT_RESULT=current/computer_metaschema-inspector.xsl + +ADDITIONAL_ARGS=$(echo ${*// /\\ }) + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" +POM_FILE="${SCRIPT_DIR}/../../../../support/pom.xml" + +MAIN_CLASS="net.sf.saxon.Transform" # Saxon defined in pom.xml + +if [ -e "$XSLT_RESULT" ] +then + echo "Deleting prior $XSLT_RESULT ..." + rm -f ./$XSLT_RESULT +fi + +mvn \ + -quiet \ + -f "$POM_FILE" \ + exec:java \ + -Dexec.mainClass="$MAIN_CLASS" \ + -Dexec.args="-xsl:${SCRIPT_DIR}/../../nist-metaschema-MAKE-INSPECTOR-XSLT.xsl -s:\"$METASCHEMA_SOURCE\" -o:\"$XSLT_RESULT\" $ADDITIONAL_ARGS" + +if [ -e "$XSLT_RESULT" ] +then + echo "XSLT written to file $XSLT_RESULT" +fi diff --git a/src/schema-gen/InspectorXSLT/testing/refresh-computer-inspector.sh b/src/schema-gen/InspectorXSLT/testing/refresh-computer-inspector.sh new file mode 100644 index 00000000..f010ebbf --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/refresh-computer-inspector.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=../common/subcommand_common.bash + +source "$SCRIPT_DIR/../../../common/subcommand_common.bash" + +# XProc produces Inspector XSLT with a fail-safe check by compiling and running it +XPROC_FILE="${SCRIPT_DIR}/COMPUTER-INSPECTOR-PRODUCE.xpl" + +XSLT_RESULT=${SCRIPT_DIR}/current/computer_metaschema-inspector.xsl + +usage() { + cat <&2 + exit 1 +fi + +[[ -z "${1-}" ]] && { echo "Error: METASCHEMA_SOURCE not specified"; usage; exit 1; } +METASCHEMA_SOURCE=$1 + +if [ ! -f "${METASCHEMA_SOURCE}" ]; then + echo "${METASCHEMA_SOURCE} not found." +fi + +XSLT_RESULT=current/$(basename "$METASCHEMA_SOURCE" .xml)-inspectorX.xsl + +ADDITIONAL_ARGS=$(shift 1; echo ${*// /\\ }) + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" +POM_FILE="${SCRIPT_DIR}/../../../../support/pom.xml" + +MAIN_CLASS="net.sf.saxon.Transform" # Saxon defined in pom.xml + +if [ -e "$XSLT_RESULT" ] +then + echo "Deleting prior $XSLT_RESULT ..." + rm -f ./$XSLT_RESULT +fi + +mvn \ + -quiet \ + -f "$POM_FILE" \ + exec:java \ + -Dexec.mainClass="$MAIN_CLASS" \ + -Dexec.args="-xsl:${SCRIPT_DIR}/../../nist-metaschema-MAKE-INSPECTOR-XSLT.xsl -s:\"$METASCHEMA_SOURCE\" -o:\"$XSLT_RESULT\" $ADDITIONAL_ARGS" + +if [ -e "$XSLT_RESULT" ] +then + echo "XSLT written to file $XSLT_RESULT" +fi diff --git a/src/schema-gen/InspectorXSLT/testing/refresh-test-inspectors.sh b/src/schema-gen/InspectorXSLT/testing/refresh-test-inspectors.sh new file mode 100644 index 00000000..ac4841f1 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/refresh-test-inspectors.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=../common/subcommand_common.bash + +source "$SCRIPT_DIR/../../../common/subcommand_common.bash" + +# XProc produces Inspector XSLT with a fail-safe check by compiling and running it +XPROC_FILE="file:${SCRIPT_DIR}/CURRENT-TEST-MODELS-REFRESH.xpl" + +usage() { + cat < + + + + + + + AVCV value-not-allowed + MRCV regex-match-fail + MDCV datatype-match-fail + XPKT expectation-violation + HCCV cardinality-violation + UNIQ uniqueness-violation + NXHK index-lookup-fail + + + + + + + + special + + + + + Value special does not appear among permissible (enumerated) values for this type: at|atx|mini-itx. + + + + + + + + + + + + Value of element type does not conform to string datatype. + Value (empty) does not appear among permissible (enumerated) values for this type: at|atx|mini-itx. + + + + + + + CUSTOM + + + + + Value CUSTOM does not appear among permissible (enumerated) values for this type: at|atx|mini-itx. + + + + + + + custom + + + + + Value custom of element type does not conform to string datatype. + Value custom does not appear among permissible (enumerated) values for this type: at|atx|mini-itx. + + + + + + + mini-itx + + + + + + + + + + + + + + Value 2001-01-01 does not appear among permissible (enumerated) values for this date-of-manufacture: 1980-04-01|1981-04-01|1982-04-01. + + + + + + + + + + + + + + + + + + + + + + + + + + + + Counting memory under /computer/motherboard finds 14 - expecting at least 2, no more than 12. + + + + + + + + + + + + + Counting memory under /computer/motherboard finds 1 - expecting at least 2, no more than 12. + Expression result for /computer/motherboard does not conform to expectation not(count(child::memory) mod 2). + + + + + + + + 512 + 512 + 512 + 512 + + + + + + + + + + + + + + + + + Counting expansion-card under computer finds 5 - expecting no more than 4. + + + + + + + + + + + + not a number does not match the regular expression defined for this serial-number: ^\S+$. + + + + + + + + 1200MHz + + + + + + + + + + + + 1200KHz + + + + + + + 1200KHz does not match the regular expression defined for this speed: \d+(?:\.\d+)?(?:MHz|GHz). + + + + + + + + + + + + + + Value of element speed does not conform to string datatype. + + (empty) does not match the regular expression defined for this speed: \d+(?:\.\d+)?(?:MHz|GHz). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + With respect to its assigned index value, this expansion-card is expected to correspond within its motherboard to a value listed under index socket-by-slot. This index has no entry under the key value 4. + + + + + + + + + + + + + + + + + + + With respect to its assigned (@slot-no), this ata-socket instance of /computer/motherboard/(ata-socket) is expected to be unique within its motherboard. 2 items are found with the value 0. + With respect to its assigned (@slot-no), this ata-socket instance of /computer/motherboard/(ata-socket) is expected to be unique within its motherboard. 2 items are found with the value 0. + + + + + + + + + + + + + + + + + + + + + + + + + + With respect to its assigned (@serial-number), this memory instance of computer/(descendant::*[exists(@serial-number)]) is expected to be unique within its computer. 2 items are found with the value a1. + With respect to its assigned (@serial-number), this expansion-card instance of computer/(descendant::*[exists(@serial-number)]) is expected to be unique within its computer. 2 items are found with the value a1. + + + + + + + + 1949-12-31T17:41:39.435735300-05:00 + + + + Expression result for /computer/build-date does not conform to expectation not(. castable as xs:dateTime) or not(xs:dateTime('1970-01-01T00:00:00-05:00') > xs:dateTime(.)). + + + + + + 1989-12-31T17:41:39.435735300-05:00 + + + + + + + + + + 256 + + + + + + + + + + + + + + + + + + + + + Expression result for /computer/motherboard does not conform to expectation not(count(child::memory) mod 2). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Value 2001-01-01 does not appear among permissible (enumerated) values for this date-of-manufacture: 1980-04-01|1981-04-01|1982-04-01. + + + + + + + + + Value today of attribute @date-of-manufacture does not conform to date datatype. + + + + + + + + + Value today does not appear among permissible (enumerated) values for this date-of-manufacture: 1980-04-01|1981-04-01|1982-04-01. + Value today of attribute @date-of-manufacture does not conform to date datatype. + + + + + + + + + + + + diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/computer-modeling.xspec b/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/computer-modeling.xspec new file mode 100644 index 00000000..a6a538c7 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/computer-modeling.xspec @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + Element motherboard is not permitted here. + + + + + + + + + + Element computer is not permitted here. + + + + + + + + + CompuTek I + + + + Attribute @illuminated is not permitted here. + + + + + + + + + + + + + + + + Value truE of attribute @illuminated does not conform to boolean datatype. + + + + + + + + + + + + + + + Element fan appears too few times: 2 minimum are required. + + + + + + + + + atx + mini-itx + + + + + Element type appears too many times: 1 maximum is permitted. + + + + + + + + + + + + + + + + + + + + Element fan is unexpected along with water. + + + + + + + + + + + mini-itx + + + + + Element type is unexpected following cpu, ata-socket, memory, cooling, or expansion-card. + + + + + + + + + + + + special + + + + + Value special does not appear among permissible (enumerated) values for this type: at|atx|mini-itx. + + + + + + + + + + + + Value of element type does not conform to string datatype. + Value (empty) does not appear among permissible (enumerated) values for this type: at|atx|mini-itx. + + + + + + + CUSTOM + + + + + Value CUSTOM does not appear among permissible (enumerated) values for this type: at|atx|mini-itx. + + + + + + + mini - itx + + + + + Value mini - itx does not appear among permissible (enumerated) values for this type: at|atx|mini-itx. + + + + + + + mini-itx + + + + + + + + + + + + + + + + + + + + + Element cooling requires element fan|water. + + + + + + + + CompuTek I + + + + Element computer requires attribute @id. + + + + + + + + + + + + Unrecognized element motherboid. + + + + + + + + + + CompuTek I + + + + Unrecognized attribute @networkID on element computer. + + + + + + + + + + + +

Here is some good bold stuff.

+
+
+
+
+ + + +

Here is some good bold stuff.

+
+
+
+
+ + + + +
+ +
diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/tiny-markupdatatypes.xspec b/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/tiny-markupdatatypes.xspec new file mode 100644 index 00000000..8c71dcba --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/tiny-markupdatatypes.xspec @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + My Tiny Data + + + + + + + My Tiny Data + + + + + + + diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/validations-in-batch.xspec b/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/validations-in-batch.xspec new file mode 100644 index 00000000..bb5540b4 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/validations-in-batch.xspec @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/xspec-patterns.xspec b/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/xspec-patterns.xspec new file mode 100644 index 00000000..c3fb7592 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-functional-xspec/xspec-patterns.xspec @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Computer Model + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Unrecognized element e. + + + + + + + + + + + + Unrecognized attribute @nope on element computer. + + + + + + + + + + + + + + + + + + + + + + + + + Unrecognized element nil. + + + + + + + + + + + + + + + name0 +
address0
+ http://pages.nist.gov/metaschema +
+ +
+
+
+ +
+ + + + +
+ +
diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/boilerplate-testing.xsl b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/boilerplate-testing.xsl new file mode 100644 index 00000000..6347aa2b --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/boilerplate-testing.xsl @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/copy_me.xsl b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/copy_me.xsl new file mode 100644 index 00000000..6e34968e --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/copy_me.xsl @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/datatype-testing.xspec b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/datatype-testing.xspec new file mode 100644 index 00000000..72c2963a --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/datatype-testing.xspec @@ -0,0 +1,155 @@ + + + + + + + + + + + + + ... + + + + + + + + + + + ... + + + + + + ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DateTimeDatatype + + string(.) castable as xs:dateTime and matches(.,'^(((2000|2400|2800|(19|2[0-9](0[48]|[2468][048]|[13579][26])))-02-29)|(((19|2[0-9])[0-9]{2})-02-(0[1-9]|1[0-9]|2[0-8]))|(((19|2[0-9])[0-9]{2})-(0[13578]|10|12)-(0[1-9]|[12][0-9]|3[01]))|(((19|2[0-9])[0-9]{2})-(0[469]|11)-(0[1-9]|[12][0-9]|30)))T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|(-((0[0-9]|1[0-2]):00|0[39]:30)|\+((0[0-9]|1[0-4]):00|(0[34569]|10):30|(0[58]|12):45)))?$') + + + + DateTimeWithTimezoneDatatype + + + + + + DateTimeWithTimezoneDatatype + + + + + + + + + + + + + + diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/inspector-production-functions.xspec b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/inspector-production-functions.xspec new file mode 100644 index 00000000..54c6088b --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/inspector-production-functions.xspec @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/produce-inspector.xspec b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/produce-inspector.xspec new file mode 100644 index 00000000..38c2b748 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/produce-inspector.xspec @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + Computer Model + 0.0.5 + computer + http://example.com/ns/computer + http://example.com/ns/computer + + + + ... + + + + + + + + ... + + + + + + ... + + + + + + + + + + diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/test-inpector-boilerplate.xspec b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/test-inpector-boilerplate.xspec new file mode 100644 index 00000000..cdec8173 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/test-inpector-boilerplate.xspec @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + A title +

A paragraph.

+
+
+
+ +
+ +
+ + + + + A title + + + + + + A title <a href="boo.html">with a link</a> and <b>extra</b>. + + + + + + + A title <a HREF="boo.html">with a link</a> and <B/>. + + + A title <a HREF="boo.html"> + <mx:report cf="..." test="exists(.)" class="_UA unmatched-attribute" xpath="/title/a/@HREF" + level="ERROR">Unrecognized attribute <mx:gi>@HREF</mx:gi> on element <mx:gi>a</mx:gi>.</mx:report>with a link</a> and <B> + <mx:report cf="..." test="exists(.)" class="_UE unmatched-element" xpath="/title/B" + level="ERROR">Unrecognized element <mx:gi>B</mx:gi>.</mx:report> + </B>. + + + +
diff --git a/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/xspec-smoketest.xspec b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/xspec-smoketest.xspec new file mode 100644 index 00000000..851a167a --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tests/inspector-generation-xspec/xspec-smoketest.xspec @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/schema-gen/InspectorXSLT/testing/tiny_metaschema.xml b/src/schema-gen/InspectorXSLT/testing/tiny_metaschema.xml new file mode 100644 index 00000000..376e0525 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tiny_metaschema.xml @@ -0,0 +1,104 @@ + + + Computer Model + 0.0.5 + computer + http://example.com/ns/tinydata + http://example.com/ns/tinydata + + + +

Tiny Metaschema

+

A metaschema can be small and yet deep.

+
+ + + Tiny Data + A minimally described data set. + TINY + + Tiny ID + An identifier. + + + + + + + + Stuff + Some amount of tiny stuff. + + + + + + + + + + + + Title + markup-line example. + + + + Term + Simple string value example. + + Term identifier + A token identifying this term uniquely within the document. + + +

For a more extensive model supporting definitions, acronyms etc. build this out into an assembly. + As a field, this supports some control over the vocabulary and formatting without heavier embedded metadata.

+

Of course you could always make a structured glossary out of regular and controlled parts for your terminology, and use this inside it, potentially with title/insert.

+
+
+ + + Note + Wrapped markup-multiline example. + + + + Tiny part + A bit of tiny data. + + + + + + + Stuff + Some amount of tiny stuff. + + + + + + + + + +
diff --git a/src/schema-gen/InspectorXSLT/testing/tinydata/bigbadtiny.xml b/src/schema-gen/InspectorXSLT/testing/tinydata/bigbadtiny.xml new file mode 100644 index 00000000..0ff90628 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tinydata/bigbadtiny.xml @@ -0,0 +1,21 @@ + + + Big Bad Tiny Data +

A tiny data example sheet.

+

Find examples of both valid and invalid markup-line and markup-multiline in a pretend operational context.

+ + Some valid data +

Here's some okay markup multiline, all clear.

+

A markup zoo permits all kinds of inline markup including bold, strong, italic, emphasis, code, subscript, superscript, hypertext anchors, and img alt-text for file.jpg (insertion points and images)

+ + Valid structures +

Including:

+
    +
  • lists
  • +
  • tables
  • +
  • preformatted blocks
  • +
  • block quotes
  • +
+
+
+
diff --git a/src/schema-gen/InspectorXSLT/testing/tinydata/tiny1.xml b/src/schema-gen/InspectorXSLT/testing/tinydata/tiny1.xml new file mode 100644 index 00000000..a0404e23 --- /dev/null +++ b/src/schema-gen/InspectorXSLT/testing/tinydata/tiny1.xml @@ -0,0 +1,22 @@ + + + Hello World + + Part First + + Some part +

Some parting words.

+
+ +

Take note here.

+
+
+ + +

An endnote, with emphasis.

+
+
+
\ No newline at end of file diff --git a/src/schema-gen/METASCHEMA-INSPECTOR-XSLT.xpl b/src/schema-gen/METASCHEMA-INSPECTOR-XSLT.xpl new file mode 100644 index 00000000..5812e75b --- /dev/null +++ b/src/schema-gen/METASCHEMA-INSPECTOR-XSLT.xpl @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XSLT generated but not proof-tested ... + + + + + + + + + + + + + + + + + + + + + + + + + + Generated XSLT runs successfully on 'x' input + + + + + + + + + + + Generated XSLT fails to compile and run + + + + + + + + + + + + + diff --git a/src/schema-gen/METASCHEMA-METATRON-wip.xpl b/src/schema-gen/METASCHEMA-METATRON-wip.xpl deleted file mode 100644 index d536864f..00000000 --- a/src/schema-gen/METASCHEMA-METATRON-wip.xpl +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/schema-gen/METASCHEMA-XSD-TEST.xpl b/src/schema-gen/METASCHEMA-XSD-TEST.xpl index de76cd1a..f8718207 100644 --- a/src/schema-gen/METASCHEMA-XSD-TEST.xpl +++ b/src/schema-gen/METASCHEMA-XSD-TEST.xpl @@ -16,12 +16,12 @@ - + - + diff --git a/src/schema-gen/METASCHEMA-XSD.xpl b/src/schema-gen/METASCHEMA-XSD.xpl new file mode 100644 index 00000000..52abbb97 --- /dev/null +++ b/src/schema-gen/METASCHEMA-XSD.xpl @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/schema-gen/Schematron/make-metaschema-metatron.xsl b/src/schema-gen/Schematron/make-metaschema-metatron.xsl deleted file mode 100644 index cf73b735..00000000 --- a/src/schema-gen/Schematron/make-metaschema-metatron.xsl +++ /dev/null @@ -1,629 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - no - - - yes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INDEX DEFINITIONS AS KEY DECLARATIONS - - - - - RULES - - - - - - - - - - - - - - - - - - - LEXICAL / DATATYPE VALIDATION FUNCTIONS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - not({ $condition }) or - - - - is expected to have at most of - - - - - - - - - not({ $condition }) or - - - - is expected to have at least of - - - - - - - - - not({ $condition }) or - - count({$target}) eq { xs:integer(@min-occurs) } - - - - is expected to have exactly of - - - - - - - - - - - - - - - not({ m:condition(.) }) or - - exists(key('{@name}',$lookup,ancestor::{$parent-context})) - - - - - - - - is expected to correspond to an entry in the '' index within the containing - - - - - - - - , - ( - - [matches(.,'^{.}$')] ! replace(.,'^{.}$','$1') - ) - - - - - - - not({ m:condition(.) }) or - - exists(key('{@name}',$lookup)) - - - - - - - - is expected to correspond to an entry in the '' index. - - - - - - - - - - not({ m:condition(.) }) or - - exactly-one(key('{@name}',{m:key-value(.)},ancestor::{$parent-context}))) - - - - is expected to be unique within the containing - - - - - - - - not({ m:condition(.) }) or - - count(key('{@name}',{m:key-value(.)}))=1 - - - - is expected to be unique. - - - - - - - not({ m:condition(.) }) or - - exists(self::node()[{ @test }]) - - - - fails to pass evaluation of '' - - - - - - - not({ m:condition(parent::matches) }) or - - m:datatype-validate(., '{.}') - - - - is expected to take the form of datatype ' - - - - - - - not({ m:condition(parent::matches) }) or - - matches(., '^{.}$') - - - - - - is expected to match regular expression '^$' - - - - - - - - - This - - - - - - - - - - - - not({ $this-condition }) or - - - - ({ @allow-other[.='yes']/'$silence-warnings or ' }. = ( { $value-sequence } )) - - - - - warning - - - is expected to be (one of) , not '' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - / - - - - - - - - / - - - - - - - - / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $declaration-prefix }:{ $whose/string(.) } - - - - - - - - - - - - - - - - - - - - - - - ( (: ... not liking absolute path - - ... :) ) - - - - (parent|ancestor|ancestor-or-self|preceding-sibling|preceding):: - - - (: not liking the reverse axis - - :) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { if ($count eq 1) then ('one ' || $noun) else ($count || ' ' || $noun || 's' ) } - - - - - [[See {local-name()}#{.}]] - - - - - - - - - - - - - - / - - - - - - - yes - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/schema-gen/Schematron/metatron-datatype-functions.xsl b/src/schema-gen/Schematron/metatron-datatype-functions.xsl deleted file mode 100644 index b70ff7af..00000000 --- a/src/schema-gen/Schematron/metatron-datatype-functions.xsl +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - ../../../support/metaschema/ - - {$metaschema-repository}/schema/xml/metaschema-datatypes.xsd - - - - - - - - - - - - - - - - - - - - - - string - string - NCName - { $nominal-type } - - - - {$value} - - - - - - - - - - - - - - - - - - - - true() - - - - - - - - - - - - - - - - - - - - diff --git a/src/schema-gen/TESTING.md b/src/schema-gen/TESTING.md index 807ad508..aad87dd1 100644 --- a/src/schema-gen/TESTING.md +++ b/src/schema-gen/TESTING.md @@ -25,3 +25,22 @@ Use models_metaschema.xml XProc to generate a schema dynamically and then validate a set of documents? +## XSD Schemas + +XSD Schema production was not originally developed using test-driven-development practices. We are now catching up. + +Work to be done includes comprehensive XSpecs for XSD production. A dependency for this is a specification for how to represent Metaschema in XSD, either established by Metaschema itself, or for this application. The current XSD generated provides a place to start. + +## JSON Schemas + +The pipelines generating JSON Schema have some ad-hoc unit testing developed to support bug fixing, buts await comprehensive unit tests. + +A separate work item is to update this generation to support more recent versions of JSON Schema - while that too demands unit tests. + +## InspectorXSLT + +The InspectorXSLT application produces an XSLT representing the constraints defined by a Metaschema, both model-based constraints (thereby in emulation of grammar-based validators such as XML DTD, W3C XSD and ISO RelaxNG) and constraints based on arbitrary assertions. + +It thus combines in one the functional properties of Schematron with XSD used as a validation application. + +Its testing is also the most advanced in this repository at time of writing, including smoke tests, unit tests and specification testing, and growing. See documentation in the folder including [readme](InspectorXSLT/readme.md) and [testing](InspectorXSLT/TESTING.md) documentation. diff --git a/src/schema-gen/mvn-inspectorXSLT-xsl.sh b/src/schema-gen/mvn-inspectorXSLT-xsl.sh new file mode 100644 index 00000000..c939c3a6 --- /dev/null +++ b/src/schema-gen/mvn-inspectorXSLT-xsl.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Fail early if an error occurs +set -Eeuo pipefail + +usage() { + cat <&2 + exit 1 +fi + +[[ -z "${1-}" ]] && { echo "Error: METASCHEMA_SOURCE not specified"; usage; exit 1; } +METASCHEMA_SOURCE=$1 +[[ -z "${2-}" ]] && { echo "Error: XSLT_RESULT not specified"; usage; exit 1; } +XSLT_RESULT=$2 + +ADDITIONAL_ARGS=$(shift 2; echo ${*// /\\ }) + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" +POM_FILE="${SCRIPT_DIR}/../../support/pom.xml" + +MAIN_CLASS="net.sf.saxon.Transform" # Saxon defined in pom.xml + +if [ -e "$XSLT_RESULT" ] +then + echo "Deleting prior $XSLT_RESULT ..." + rm -f ./$XSLT_RESULT +fi + +mvn \ + -f "$POM_FILE" \ + exec:java \ + -Dexec.mainClass="$MAIN_CLASS" \ + -Dexec.args="-xsl:${SCRIPT_DIR}/nist-metaschema-MAKE-INSPECTOR-XSLT.xsl -s:\"$METASCHEMA_SOURCE\" -o:\"$XSLT_RESULT\" $ADDITIONAL_ARGS" + +if [ -e "$XSLT_RESULT" ] +then + echo "XSLT transformation written to file $XSLT_RESULT" +fi diff --git a/src/schema-gen/nist-metaschema-MAKE-XML-METATRON.xsl b/src/schema-gen/nist-metaschema-MAKE-INSPECTOR-XSLT.xsl similarity index 85% rename from src/schema-gen/nist-metaschema-MAKE-XML-METATRON.xsl rename to src/schema-gen/nist-metaschema-MAKE-INSPECTOR-XSLT.xsl index b0019749..d2188393 100644 --- a/src/schema-gen/nist-metaschema-MAKE-XML-METATRON.xsl +++ b/src/schema-gen/nist-metaschema-MAKE-INSPECTOR-XSLT.xsl @@ -5,12 +5,12 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all"> - + - + - + + + + + + + + + \ No newline at end of file diff --git a/src/util/oxygen-refactoring-xspec-renumber.xml b/src/util/oxygen-refactoring-xspec-renumber.xml new file mode 100644 index 00000000..56bf772c --- /dev/null +++ b/src/util/oxygen-refactoring-xspec-renumber.xml @@ -0,0 +1,9 @@ + + + Provides every x:scenario/@label with a distinct hierarchical number reflecting its position. +