Schematron - using variables in XPATH

This should cover W3C XML Schema, Relax NG and DTD related problems.
Richard_Wood
Posts: 12

Schematron - using variables in XPATH

Fri Apr 15, 2016 1:10 am

Hello,
I am trying to create a variable ($refValue) using XPATH to capture a value from an XML file that I ultimately want to validate.
Then I want to use that variable along with a variable created using the document() function (which references an external XML file), apended with an XPATH to capture a value from an external XML file to create another variable($qualifierValue) .
I then want to use the second variable ($qualifierValue) in validations in my report element.
I set all of the variables inside of the rule element, prior to the assert element.

When I display the contents of $qualifierValue in a report element, it apears empty
But if I display the documet()//XPATH used to set $qualifierValue, the expected value is present, namely "MY"

I saw one post, that appeared to say I can't use variables in XPATH to test attribute values, but I am not sure of that.

I will include my Schematron schema, the XML file that I am trying to validate, and the external XML files that I am trying to reference.
I use a report element to show the values of my variables. I will include that output too.

The assertion should be true, but it reports indicating that the test fails.
I've tried a lot of different approaches. There must be something about setting variables using XPATH and variables that I don't know.

Help please, what am I doing that is wrong?

First, here is the output of using the schema against the XML in OxygenXML 17.1

context = AMM;
registryItemValue = AMM;
refValue = MY-SHOP;
refPath = http://docs.my.company.com:8180/DDMFReg ... Providers;
refXmlFilename = ;
qualifierValue1 = ; <== This is the value-of the $qualifierValue
qualifierValue2 = MY; <== This is the value of the "value" attribute that is supposed to set the $qualifierValue
path = http://docs.my.company.com:8180/DDMFReg ... mentTypes;
registryXmlFilename = ;

Here is the output of the assert that also comes out when I run the schema:
This DDMF XML references a / Document/ documentType of: AMM which does not exist in the registry.

Here is the Schematron schema:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
    <sch:ns uri="http://www.w3.org/2001/XMLSchema-instance" prefix="isx"/>
    <sch:pattern id="validateDocumentType">
        <sch:rule context="//Document/documentType">
            <sch:let name="registryItemValue" value="normalize-space(.)"/>
            <sch:let name="refValue" value="//Document/dataProvider"/>
            <sch:let name="refPath" value="'http://docs.my.company.com:8180/DDMFRegistryService/registry/XML/dataProviders'"/>
            <sch:let name="refXmlFilename" value="document($refPath)"/>
            <sch:let name="qualifierValue" value="$refXmlFilename//registry/entry/item[@key='dataProvider' and @value='$refValue']/../item[@key='ns']/@value"/>
            <sch:let name="path"  value="'http://docs.my.company.com:8180/DDMFRegistryService/registry/XML/documentTypes'"/>
            <sch:let name="registryXmlFilename" value="document($path)"/>
            <!-- debugging test -->
            <sch:report role="warn" test="true()">
                <!-- change this to true() for debugging -->
                context = <sch:value-of select="//Document/documentType"/>;
                registryItemValue = <sch:value-of select="$registryItemValue"/>;
                refValue = <sch:value-of select="$refValue"/>;
                refPath = <sch:value-of select="$refPath"/>;
                refXmlFilename = <sch:value-of select="$refXmlFilename"/>;
                qualifierValue1 = <sch:value-of select="$qualifierValue"/>;
                qualifierValue2 = <sch:value-of select="$refXmlFilename//registry/entry/item[@key='dataProvider' and @value='MY-SHOP']/../item[@key='ns']/@value"/>;
                path = <sch:value-of select="$path"/>;
                registryXmlFilename = <sch:value-of select="$refXmlFilename"/>;
            </sch:report>
            <sch:assert role="error"
                test="$registryXmlFilename//registry/entry/item[
                @key=documentType
                and @value = $registryItemValue]
                /../item[@key='ns']
                /@value=$qualifierValue" >
                This DDMF XML references a
                <sch:value-of select="name(../..)"/>/
                <sch:value-of select="name(..)"/>/
                <sch:value-of select="name()"/> of:
                <sch:value-of select="."/> which does
                not exist in the registry.
            </sch:assert>
        </sch:rule>
    </sch:pattern>
</sch:schema>


Here is one external XML file (associated with the $refPath variable):
http://docs.my.company.com:8180/DDMFReg ... aProviders

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<registry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://dast.my.company.com/assets/registry/schema/1-0/registry.xsd"
schemaVersion="1.0" identity="dataProviders"
modified="2016-02-05T21:19:00Z">
  <entry status="stable" modified="2016-02-04T21:36:00Z" >
    <item key="ns" value="MY" />
    <item key="dataProvider" value="MY-SHOP" />
  </entry>
  <entry status="stable" modified="2016-02-04T21:36:00Z" >
    <item key="ns" value="YOUR" />
    <item key="dataProvider" value="YOUR-SHOP" />
  </entry>
</registry>


Here is the second external XML file (associated with the $path variable):
http://docs.my.Company.com:8180/DDMFReg ... umentTypes

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<registry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://dast.my.company.com/assets/registry/schema/1-0/registry.xsd"
schemaVersion="1.0" identity="documentTypes"
modified="2016-04-13T20:35:42Z">
  <entry status="unstable" modified="2015-07-07T17:30:00Z" >
    <item key="ns" value="YOUR" />
    <item key="documentType" value="AMM" />
  </entry>
  <entry status="stable" modified="2015-07-07T17:30:00Z" >
    <item key="ns" value="MY" />
    <item key="documentType" value="AMM" />
  </entry>
</registry>


Here is the XML file that I am trying to validate:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://www.my.company.com/ddmf/ddmf.xsd"
  schemaVersion="3.0">
  <status>TEST</status>
  <packageTimestamp>2015-03-11T12:00:00Z</packageTimestamp>
  <dataProvider>MY-SHOP</dataProvider>
  <documentType>AMM</documentType>
</Document>
tavy
Posts: 122

Re: Schematron - using variables in XPATH

Fri Apr 15, 2016 10:42 am

Hello,

I corrected your Schematron schema, you can find it below. You made some small mistakes:
- in the 'qualifierValue' variable the $refValue should not be in apostrophes, instead of @value='$refValue' use @value=$refValue.
- in the assert you need to use apostrophes for documentType, instead of @key=documentType use @key='documentType'.

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
    <sch:ns uri="http://www.w3.org/2001/XMLSchema-instance" prefix="isx"/>
    <sch:pattern id="validateDocumentType">
        <sch:rule context="//Document/documentType">
            <sch:let name="registryItemValue" value="normalize-space(.)"/>
            <sch:let name="refValue" value="//Document/dataProvider"/>
            <sch:let name="refPath" value="'http://docs.my.company.com:8180/DDMFRegistryService/registry/XML/dataProviders'"/>
            <sch:let name="refXmlFilename" value="document($refPath)"/>
            <sch:let name="qualifierValue" value="$refXmlFilename//registry/entry/item[@key='dataProvider' and @value=$refValue]/../item[@key='ns']/@value"/>
            <sch:let name="path"  value="'http://docs.my.company.com:8180/DDMFRegistryService/registry/XML/documentTypes'"/>
            <sch:let name="registryXmlFilename" value="document($path)"/>
            <!-- debugging test -->
            <sch:report role="warn" test="true()">
                <!-- change this to true() for debugging -->
                context = <sch:value-of select="//Document/documentType"/>;
                registryItemValue = <sch:value-of select="$registryItemValue"/>;
                refValue = <sch:value-of select="$refValue"/>;
                refPath = <sch:value-of select="$refPath"/>;
                refXmlFilename = <sch:value-of select="$refXmlFilename"/>;
                qualifierValue1 = <sch:value-of select="$qualifierValue"/>;
                qualifierValue2 = <sch:value-of select="$refXmlFilename//registry/entry/item[@key='dataProvider' and @value='MY-SHOP']/../item[@key='ns']/@value"/>;
                path = <sch:value-of select="$path"/>;
                registryXmlFilename = <sch:value-of select="$refXmlFilename"/>;
            </sch:report>
            <sch:assert role="error"
                test="$registryXmlFilename//registry/entry/item[
                @key='documentType'
                and @value = $registryItemValue]
                /../item[@key='ns']
                /@value=$qualifierValue" >
                This DDMF XML references a
                <sch:value-of select="name(../..)"/>/
                <sch:value-of select="name(..)"/>/
                <sch:value-of select="name()"/> of:
                <sch:value-of select="."/> which does
                not exist in the registry.
            </sch:assert>
        </sch:rule>
    </sch:pattern>
</sch:schema>


Best Regards,
Octavian
Octavian Nadolu
<oXygen/> XML Editor
http://www.oxygenxml.com
Richard_Wood
Posts: 12

Re: Schematron - using variables in XPATH

Mon Apr 18, 2016 8:17 pm

Thank-you Octavian,

I have now resolved all of my issues (I only documented one) based on your corrections and confidence that what I was trying to do was in fact possible.

I am particularly pleased to have this schema working. We have many complex validations which will involve multiple elements and multiple registry table look-up values. Thanks for the confidence to persevere!

Regards,

Rich Wood

Return to “XML Schemas”

Who is online

Users browsing this forum: No registered users and 1 guest