Page 1 of 1

Validation with XQuery instead of schematron

Posted: Thu Mar 25, 2021 9:19 pm
by Graydon2014
XQuery is much more capable than Schematron, and when writing style checking rules I'd much rather use XQuery.

It's straightforward to create an XQuery transformation scenario, but the scenario does not run automatically in the way validation does as part of a document type association.

How do I get an XQuery into a document type association so that it will run automatically?

Thanks!

Re: Validation with XQuery instead of schematron

Posted: Fri Mar 26, 2021 1:11 pm
by adrian
Hello,

Technically it's possible via a custom validation engine, but it's a little complicated and there are some limitations (no automatic validation - as you type).
If you are a Java developer, there is a another way to do this by implementing a Workspace Access plugin and that also works for automatic validation.

There may be an aspect you have not considered when using XQuery, location, location, location :).
IMHO, it would be preferable to stick with Schematron or similar means of validation. Have you considered XPath 3.0 or XSLT 3.0 within Schematron?

The custom validation engine solution
There is a significant difference between a validation engine output and a transformation engine output. The validation engine must provide a list of results (errors/warnings/info) and each of these should specify a SystemID for the file, location of the error/warning within the file (line, column, endLine, endColumn) and description (message). The specification for the output of an external validation engine that Oxygen recognizes is available here Custom Validators > Linked Output Messages of an External Engine

If your XQuery provides such an output, you can configure a custom validation engine in Options > Preferences, Editor > Document Validation > Custom Validation Engines that runs your XQuery.
This will run your XQuery (via command line Saxon XQuery) against the current XML file and Oxygen will expect the output to be text in the format from the link I provided above.
Configure the custom validation engine this way:
Name: MyXQueryValidation
Executable path: ${oxygenInstallDir}/jre/bin/java (This points to the Java runtime bundled with Oxygen)
Associated Editors: Press + and select "XML Editor"
Command line arguments for detected schemas
XSD: -cp "${oxygenInstallDir}/lib/oxygen-patched-saxon-9.jar;${oxygenInstallDir}/lib/oxygen-basic-utilities.jar" net.sf.saxon.Query "file:/path/to/my.xquery" "-s:${cf}"
You may have to copy this line for all types of schemas.

I have used a dummy XQuery for testing, "my.xquery":

Code: Select all

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "text";
concat("Type: E
SystemID: ",
base-uri(),
"
Line: 11
Column: 20
EndLine: 11
EndColumn: 35
Description: My custom error message")
Once you have this set up, you can test it on an XML file via the drop down list of the Validate toolbar action (Oxygen main toolbar). Among LIBXML, Saxon-EE and MSXML you should also find the "MyXQueryValidation".
Once this is working, you can proceed and add a new validation unit that uses the MyXQueryValidation engine to any validation scenario, including the ones from document type associations. This is where you will notice that you cannot enable automatic validation for this type of validation engine. The reason is this is in fact a command line validation that only works on the file from the file system (saved file).


The Workspace Access plugin solution - starting point
If you are a Java developer, you can use our Oxygen Java API and implement a Workspace Access plugin that can intercept validation events via a ValidationProblemsFilter, run your XQuery from Java code on the editor contents and append its results to the list of validation problems.
A good starting point for such a plugin is available on Github:
https://github.com/oxygenxml/sample-plu ... ace-access
Here's a code snippet showing the API that can help (courtesy of my colleague Alex Jitianu):

Code: Select all

  /**
   * @see ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension#applicationStarted(ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace)
   */
  @Override
  public void applicationStarted(final StandalonePluginWorkspace pluginWorkspaceAccess) {
   
    pluginWorkspaceAccess.addEditorChangeListener(new WSEditorChangeListener() {
      @Override
      public void editorOpened(URL editorLocation) {
        WSEditor editorAccess = pluginWorkspaceAccess.getEditorAccess(editorLocation, PluginWorkspace.MAIN_EDITING_AREA);
        editorAccess.addValidationProblemsFilter(new ValidationProblemsFilter() {
          @Override
          public void filterValidationProblems(ValidationProblems validationProblems) {
            List<DocumentPositionedInfo> allProblems = new ArrayList<>();
            if (validationProblems.getProblemsList() != null) {
              allProblems.addAll(validationProblems.getProblemsList());
            }
            // TODO Run XQuery and merge problems
            allProblems.addAll(xqueryObtainedProblems);
           
            validationProblems.setProblemsList(allProblems);
          }
        });
      }
    }, PluginWorkspace.MAIN_EDITING_AREA);
Regards,
Adrian

Re: Validation with XQuery instead of schematron

Posted: Fri Mar 26, 2021 3:16 pm
by Graydon2014
Thank you, Adrian!

This is laudably thorough.

IMHO, it would be preferable to stick with Schematron or similar means of validation. Have you considered XPath 3.0 or XSLT 3.0 within Schematron?

Schematron provides a subset of XPath expressions; capable as XPath 3.1 is, FLOWR expressions and the concept of processing a tuple stream are considerably more capable. Also cleaner and simpler to write and maintain.