Page 1 of 1

Resolving IDrefs and idref() function help

Posted: Thu Feb 06, 2020 7:59 pm
by corymosiman12
Hello,

I am needing to use ISO Schematron validation for the following scenario:

I have elements defined which have an IDref attribute (defined as follows)

Code: Select all

 <xs:attribute name="IDref" type="xs:IDREF" use="required"/> 


which are meant to link to an auc:Section element in the following way:

Code: Select all

          <auc:PlugLoad ID="PlugLoad-Office">
            <auc:PlugLoadType>Miscellaneous Electric Load</auc:PlugLoadType>
            <auc:WeightedAverageLoad>0.75</auc:WeightedAverageLoad>
            <auc:LinkedPremises>
              <auc:Section>
                <auc:LinkedSectionID IDref="Section-Office"></auc:LinkedSectionID>
              </auc:Section>
            </auc:LinkedPremises>
          </auc:PlugLoad>
This is one of three different elements (the other two being a auc:HVACSystem and auc:LightingSystem) that should link back to an auc:Section element.

I am then trying to validate that each auc:Section element defined is referenced by exactly one of each type of an auc:PlugLoad, auc:HVACSystem, and auc:LightingSystem.

I have had success using XPath 2.0 SA and XPath 3.0 SA (in the XPath/XQuery Builder part) to run the query:

Code: Select all

idref(//auc:Section/@ID)
which returns all of the auc:LinkedSectionID elements (which I could then navigate upwards using relative paths or the ancestor:: function to check the type of the element).

However, when I attempt to Validate the file using a similar expression in Schematron, I don't get anything to return. The function I have written is as follows:

Code: Select all

<!--
    Require that each auc:Section element is referenced to by exactly one of 
    each of the following elements via an @IDref:
    1. auc:Systems/auc:HVACSystems/auc:HVACSystem/auc:LinkedPremises/auc:Section/auc:LinkedSectionID
    2. auc:System/auc:LightingSystems/auc:LightingSystem/auc:LinkedPremises/auc:Section/auc:LinkedSectionID
    3. auc:System/auc:PlugLoads/auc:PlugLoad/auc:LinkedPremises/auc:Section/auc:LinkedSectionID
    <param> parent - an auc:Section element
-->
  <pattern abstract="true" id="sec.primarySystems">
    <rule context="$parent" role="error">
      <let name="sectionId" value="@ID"/>
      <let name="systemsElements" value="ancestor::auc:Facility/auc:Systems"/>
      <let name="hvacSystems" value="$systemsElements/auc:HVACSystems/auc:HVACSystem"/>
      <let name="hvacIDrefs" value="$hvacSystems//auc:LinkedSectionID/@IDref"/>
      <let name="idFromIdref" value="idref(@ID)"/>
      <let name="count" value="count(data($hvacIDrefs) = data($sectionId))"/>
      <assert test="false()">
        <name/> has id: <value-of select="$sectionId"/>
      </assert>
      <assert test="false()">
        HVAC IDRefs: <value-of select="$hvacIDrefs"/>
      </assert>
      <assert test="false()">
        <value-of select="$count"/>
      </assert>
      <assert test="false()">
        idFromIdref: <value-of select="$idFromIdref"/>
      </assert>
    </rule>
  </pattern>
  
I have asserted all as false just for error checking. When I run this, it generates the following:
Screen Shot 2020-02-06 at 11.50.15 AM.png
Screen Shot 2020-02-06 at 11.50.15 AM.png (65.5 KiB) Viewed 1358 times
So, my questions are:
1. Should the idref() function work? Based on this link, it appears that it should work for XPath 2.0 (which is I believe what ISO-Schematron uses?)
2. If not, is there another similar strategy to make work?

A sample of this XML can be found here

Re: Resolving IDrefs and idref() function help

Posted: Fri Feb 07, 2020 1:42 pm
by tavy
Hello,

I think that the "idref()" function will work only if you use Saxon-EE (schema-aware) for Schematron validation. For this you need to enable the "Use Saxon EE (schema aware) for xslt2/xslt3 query language binding" option from Options->Preferences dialog -> "XML / XML Parser / Schematron" option page.

Best Regards,
Octavian