ph-schematron icon indicating copy to clipboard operation
ph-schematron copied to clipboard

XPath 2 variable substitution in Pure Schematron

Open qligier opened this issue 4 years ago • 4 comments

Hi, I'm trying to use the Pure Schematron validator but I've encountered an issue with variable substitution. The Schematron I deal with uses let statements with XPath 2 patterns, and an example of problematic rule is:

<rule>
  <let name="xsiLocalName"
       value="if (contains(@xsi:type, ':')) then substring-after(@xsi:type,':') else @xsi:type"/>
  <let name="xsiLocalNS"
       value="if (contains(@xsi:type, ':')) then namespace-uri-for-prefix(substring-before(@xsi:type,':'),.) else namespace-uri-for-prefix('',.)"/>
  <assert role="error"
          see="http://ehealthsuisse.art-decor.org/cdachemed-html-20180508T090351/tmp-1.3.6.1.4.1.19376.1.9.1.3.2-2018-01-11T130449.html"
          test="@nullFlavor or ($xsiLocalName='EIVL_TS' and $xsiLocalNS='urn:hl7-org:v3')">Error</assert>
</rule>

When the variables are resolved and replaced, the test becomes

@nullFlavor or (if (contains(@xsi:type, ':')) then substring-after(@xsi:type,':') else @xsi:type='EIVL_TS' and if (contains(@xsi:type, ':')) then namespace-uri-for-prefix(substring-before(@xsi:type,':'),.) else namespace-uri-for-prefix('',.)='urn:hl7-org:v3')

and Saxon fails to compile it (Unexpected token "if(" at start of expression). Now, if braces are added around when replacing variable names with their content, Saxon is able to compile the resulting test:

@nullFlavor or ((if (contains(@xsi:type, ':')) then substring-after(@xsi:type,':') else @xsi:type)='EIVL_TS' and (if (contains(@xsi:type, ':')) then namespace-uri-for-prefix(substring-before(@xsi:type,':'),.) else namespace-uri-for-prefix('',.))='urn:hl7-org:v3')

The validation with XSLT is working as expected. Do you have any idea on this issue? Thank you, Quentin

qligier avatar Dec 14 '19 19:12 qligier

I am afraid this seems to be the same as #88 Pure version does not handle "let" with variables correctly :(

phax avatar Dec 15 '19 00:12 phax

Query language binding for XPath 2 states:

The let element should not be used.

Oh, so variables substitution as it's implemented should only work with simpler XPath 1 expressions?

What do you think about always adding braces when substituting XPath variables? It should improve support for more complex expressions without pejorating current support (at least to my current understanding)?

qligier avatar Dec 15 '19 11:12 qligier

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Mar 14 '20 12:03 stale[bot]

Hi, I've been playing with that and have implemented a PoC inspired by the pure version to validate Schematron files, using Saxon as XQuery processor and avoiding all XSLT transformations. I think the main difference is that I don't substitute variables in the patterns but execute them with Saxon and inject the result in the following selectors. It works fine with the large Schematron files I'm dealing with, but I don't know what subset of XPath 2/XSLT is effectively used in it and if it could work with any Schematron file. Could it be of any help here? If not, I guess this issue can be closed.

qligier avatar Sep 20 '20 18:09 qligier