Page 1 of 1

using variables in test property with matches

Posted: Fri Sep 16, 2016 1:58 am
by Richard_Wood
I would like to define a set of regular expressions as variables at the top of a pattern, then use them in various combinations on multiple rule elements. I want to use them in the test property of assert and report elements. I get different results when I try to use these variables and when I use the literal regular expression. I've tried to look for similar examples without success. Not sure what I have wrong and I would appreciate having my mistake identified. Thanks!

The XML file:

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<Document>
<assignedSubject>A23-23-1234</assignedSubject>
<assignedSubject>51-00-01</assignedSubject>
<assignedSubject>51-00-02</assignedSubject>
<assignedSubject>51-00-06</assignedSubject>
</Document>
The Schematron file:

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:pattern id="regexVariableTest">
<sch:let name="regex01" value="'[A-Z]?\d\d-\d\d-\d{2}'"/>
<sch:let name="regex02" value="'[A-Z]?\d\d-\d\d-\d{4}'"/>
<sch:rule context="//assignedSubject">
<sch:assert test="matches(normalize-space(.),'
^[A-Z]?\d\d-\d\d-\d{2}$ |
^[A-Z]?\d\d-\d\d-\d{4}$
','x')"
role="error">
message:1
</sch:assert>
<sch:assert test="matches(normalize-space(.),'
^$regex01$ |
^$regex02$
','x')"
role="error">
message:2
</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
The result is that the first assert, using literal regular expressions, passes.
But the second assert, using variable representations of the regular expressions fail.
Below is the output from running the schematron.
I suspect there is a problem with my variable definition.
Thanks again for pointing out my error!

Rich Wood

Code: Select all


E[ISO Schematron] message:2
E[ISO Schematron] message:2
E[ISO Schematron] message:2
E[ISO Schematron] message:2

Re: using variables in test property with matches

Posted: Mon Sep 19, 2016 10:57 am
by Radu
Hi Rich,

Basically when the XML is validated with the Schematron, Oxygen creates an XSLT stylesheet from the Schematron and applies the XSLT stylesheet over the XML.
If you open the schematron file, and use the "Configure Transformation Scenarios" toolbar button you have a predefined scenario which can be used in order to see how the generated XSLT stylesheet looks like.

Basically when you use this construct in the Schematron:

Code: Select all

               <sch:assert test="matches(normalize-space(.),'^$regex01$ |^$regex02$','x')"
role="error">
message:2
</sch:assert>
is generated in the XSLT like this:

Code: Select all

  <xsl:when test="matches(normalize-space(.),'^$regex01$ |^$regex02$','x')"/>
Because you are inside a string literal (inside the simple quotes) the "$regex01" is not considered a variable reference, it is considered a plain string.
So in such cases you probably need to use in the Schematron the concat() function, something like:

Code: Select all

<sch:assert test="matches(normalize-space(.), concat('^', $regex01, '$|^', $regex02, '$'),'x')"
role="error">
message:2
</sch:assert>
Regards,
Radu