Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent Error Handling: XSLT-Based Resource Fails, While Pure Resource Completes Validation #171

Closed
gediminasre opened this issue Jun 10, 2024 · 6 comments
Assignees
Labels

Comments

@gediminasre
Copy link

Dear Repository Maintainer,

We are encountering an issue where there is a discrepancy between Pure and XSLT validations using the same Schematron file in version 7.1.2 of your library.

Description:

During our validation process, Pure validation logs an error message to the console but continues and completes the validation. In contrast, XSLT validation, using the same Schematron file, throws the same error and halts the validation process.

Error Messages and Files:

Issue:

For some reason, the Pure validation catches the error but does not re-throw it, whereas the XSLT validation re-throws the error, causing it to stop. This difference in behavior is causing inconsistencies in our validation workflow.

Could you please investigate why the XSLT validation behaves differently from the Pure validation in this scenario? Any insights or suggestions for achieving consistent behavior would be greatly appreciated.

Thank you for your assistance and for providing such a valuable tool.

Best regards,
Gediminas

@phax phax self-assigned this Jun 10, 2024
@phax phax added the question label Jun 10, 2024
@gediminasre
Copy link
Author

@phax perhaps you had some time to look at this?

@phax
Copy link
Owner

phax commented Jul 12, 2024

@gediminasre thanks for the reminder. Indeed there is an explanation for this.
a) Pure and XSLT behave totally different because they support a different condition language (XPath vs. XPath + XSLT) and the execution logic is different (Java vs. XSLT element iteration)
b) See e.g. #169 for another very similar case on why they behave differently

However, I acknowledge the inconsistency, that the error is not re-thrown and I will look into it

@gediminasre
Copy link
Author

Thanks for coming back @phax

To clarify, XSLT should ideally follow the Pure validation pattern and not throw the error, allowing the full validation process to complete.

@phax
Copy link
Owner

phax commented Jul 12, 2024

@gediminasre does an SVRL like this suit your needs:

<?xml version="1.0" encoding="UTF-8"?>
<svrl:schematron-output xmlns:svrl="http://purl.oclc.org/dsdl/svrl" title="eForms-DE Schematron Version @eforms-de-schematron.version.full@ compliant with eForms-DE specification @eforms-de.version.full@" phase="doe-validation-phase">
  <svrl:ns-prefix-in-attribute-values prefix="can" uri="urn:oasis:names:specification:ubl:schema:xsd:ContractAwardNotice-2" />
  <svrl:ns-prefix-in-attribute-values prefix="cn" uri="urn:oasis:names:specification:ubl:schema:xsd:ContractNotice-2" />
  <svrl:ns-prefix-in-attribute-values prefix="pin" uri="urn:oasis:names:specification:ubl:schema:xsd:PriorInformationNotice-2" />
  <svrl:ns-prefix-in-attribute-values prefix="brin" uri="http://data.europa.eu/p27/eforms-business-registration-information-notice/1" />
  <svrl:ns-prefix-in-attribute-values prefix="cbc" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" />
  <svrl:ns-prefix-in-attribute-values prefix="cac" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" />
  <svrl:ns-prefix-in-attribute-values prefix="ext" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" />
  <svrl:ns-prefix-in-attribute-values prefix="efac" uri="http://data.europa.eu/p27/eforms-ubl-extension-aggregate-components/1" />
  <svrl:ns-prefix-in-attribute-values prefix="efext" uri="http://data.europa.eu/p27/eforms-ubl-extensions/1" />
  <svrl:ns-prefix-in-attribute-values prefix="efbc" uri="http://data.europa.eu/p27/eforms-ubl-extension-basic-components/1" />
  <svrl:ns-prefix-in-attribute-values prefix="xs" uri="http://www.w3.org/2001/XMLSchema" />
  <svrl:active-pattern id="global-variable-pattern" />
  <svrl:active-pattern id="technical-sanity-pattern" />
  <svrl:fired-rule context="//$ROOT-NODE/cbc:CustomizationID" />
  <svrl:failed-assert id="SR-DE-1" location="/can:ContractAwardNotice/cbc:CustomizationID" test="text() = $EFORMS-DE-ID" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'text() = $EFORMS-DE-ID'
Error: The string "eforms-de-1.1" cannot be cast to a boolean</svrl:text>
  </svrl:failed-assert>
  <svrl:active-pattern id="cardinality-pattern" />
  <svrl:fired-rule context="//$ROOT-NODE" />
  <svrl:failed-assert id="CR-DE-BT-105" location="/can:ContractAwardNotice" test="if ($SUBTYPE = $SUBTYPES-BT-105) then             exists(cac:TenderingProcess/cbc:ProcedureCode)           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-105) then             exists(cac:TenderingProcess/cbc:ProcedureCode)           else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:fired-rule context="//$ROOT-NODE/cbc:RequestedPublicationDate" />
  <svrl:fired-rule context="//$ROOT-NODE/cac:ProcurementProject" />
  <svrl:failed-assert id="CR-DE-BT-21" location="/can:ContractAwardNotice/cac:ProcurementProject" test="boolean(normalize-space((cbc:Name[./@languageID = $MAIN-LANG])))" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'boolean(normalize-space((cbc:Name[./@languageID = $MAIN-LANG])))'
Error: The string "DEU" cannot be cast to a boolean</svrl:text>
  </svrl:failed-assert>
  <svrl:fired-rule context="//$ROOT-NODE/cac:ProcurementProject/cac:RealizedLocation" />
  <svrl:fired-rule context="//$ROOT-NODE/cac:ProcurementProjectLot[cbc:ID/@schemeName = 'Lot']/cac:ProcurementProject" />
  <svrl:failed-assert id="CR-DE-BT-21-Lot" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:ProcurementProject" test="boolean(normalize-space((cbc:Name[./@languageID = $MAIN-LANG])))" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'boolean(normalize-space((cbc:Name[./@languageID = $MAIN-LANG])))'
Error: The string "DEU" cannot be cast to a boolean</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="BR-DE-21-A" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:ProcurementProject" test="if ($SUBTYPE = $SUBTYPES-BT-06) then             (count(cac:ProcurementAdditionalType/cbc:ProcurementTypeCode[@listName = 'strategic-procurement']) ge 1)           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-06) then             (count(cac:ProcurementAdditionalType/cbc:ProcurementTypeCode[@listName = 'strategic-procurement']) ge 1)           else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="BR-DE-21-B" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:ProcurementProject" test="if ($SUBTYPE = $SUBTYPES-BT-06) then             (count(cac:ProcurementAdditionalType/cbc:ProcurementTypeCode[@listName = 'strategic-procurement']) le 3)           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-06) then             (count(cac:ProcurementAdditionalType/cbc:ProcurementTypeCode[@listName = 'strategic-procurement']) le 3)           else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="BR-DE-22" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:ProcurementProject" test="if ($SUBTYPE = $SUBTYPES-BT-06) then             (count(cac:ProcurementAdditionalType/cbc:ProcurementTypeCode[@listName = 'strategic-procurement']) = count(distinct-values(cac:ProcurementAdditionalType/cbc:ProcurementTypeCode[@listName = 'strategic-procurement'])))           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-06) then             (count(cac:ProcurementAdditionalType/cbc:ProcurementTypeCode[@listName = 'strategic-procurement']) = count(distinct-values(cac:ProcurementAdditionalType/cbc:ProcurementTypeCode[@listName = 'strategic-procurement'])))           else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:fired-rule context="//$ROOT-NODE/cac:ProcurementProjectLot[cbc:ID/@schemeName = 'Lot' or cbc:ID/@schemeName = 'Part']/cac:ProcurementProject/cac:RealizedLocation/cac:Address" />
  <svrl:fired-rule context="//$ROOT-NODE/cac:ProcurementProjectLot[cbc:ID/@schemeName = 'Lot']/cac:TenderingTerms" />
  <svrl:failed-assert id="CR-DE-BT-771-Lot" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:TenderingTerms" test="if ($SUBTYPE = $SUBTYPES-BT-771-772) then             (count(cac:TendererQualificationRequest[not(cbc:CompanyLegalFormCode)]/cac:SpecificTendererRequirement[(cbc:TendererRequirementTypeCode[@listName = 'missing-info-submission'])]) = 1)           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-771-772) then             (count(cac:TendererQualificationRequest[not(cbc:CompanyLegalFormCode)]/cac:SpecificTendererRequirement[(cbc:TendererRequirementTypeCode[@listName = 'missing-info-submission'])]) = 1)           else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="CR-DE-BT-772-Lot" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:TenderingTerms" test="if ($SUBTYPE = $SUBTYPES-BT-771-772) then             (count(cac:TendererQualificationRequest[not(cbc:CompanyLegalFormCode)]/cac:SpecificTendererRequirement[(cbc:TendererRequirementTypeCode[@listName = 'missing-info-submission'])]/cbc:Description[./@languageID = $MAIN-LANG]) = 1)                      else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-771-772) then             (count(cac:TendererQualificationRequest[not(cbc:CompanyLegalFormCode)]/cac:SpecificTendererRequirement[(cbc:TendererRequirementTypeCode[@listName = 'missing-info-submission'])]/cbc:Description[./@languageID = $MAIN-LANG]) = 1)                      else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="SR-DE-21" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:TenderingTerms" test="if ($SUBTYPE = $SUBTYPES-BT-771-772) then             (count(cac:TendererQualificationRequest) >= 1)           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-771-772) then             (count(cac:TendererQualificationRequest) &gt;= 1)           else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="CR-DE-BT-97-Lot" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:TenderingTerms" test="if ($SUBTYPE = $SUBTYPES-BT-97) then             exists(cac:Language/cbc:ID)           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-97) then             exists(cac:Language/cbc:ID)           else             true()'
Error: Cannot compare xs:boolean to xs:string</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="SR-DE-23" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:TenderingTerms" test="if ($SUBTYPE = $SUBTYPES-BT-15) then             (count(cac:CallForTendersDocumentReference) >= 1)           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-15) then             (count(cac:CallForTendersDocumentReference) &gt;= 1)           else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:fired-rule context="//$ROOT-NODE/cac:ProcurementProjectLot[cbc:ID/@schemeName = 'Lot']" />
  <svrl:failed-assert id="CR-DE-BT-63-Lot" location="/can:ContractAwardNotice/cac:ProcurementProjectLot" test="if ($SUBTYPE = $SUBTYPES-BT-63) then             boolean(normalize-space(cac:TenderingTerms/cbc:VariantConstraintCode))           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-63) then             boolean(normalize-space(cac:TenderingTerms/cbc:VariantConstraintCode))           else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="CR-DE-BT-17-Lot" location="/can:ContractAwardNotice/cac:ProcurementProjectLot" test="if ($SUBTYPE = $SUBTYPES-BT-17) then             boolean(normalize-space(cac:TenderingProcess/cbc:SubmissionMethodCode[@listName = 'esubmission']))           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-17) then             boolean(normalize-space(cac:TenderingProcess/cbc:SubmissionMethodCode[@listName = 'esubmission']))           else             true()'
Error: Cannot compare xs:boolean to xs:string</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="CR-DE-BT-717-Lot" location="/can:ContractAwardNotice/cac:ProcurementProjectLot" test="if ($SUBTYPE = $SUBTYPES-BT-717) then             exists(cac:TenderingTerms/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/efext:EformsExtension/efac:StrategicProcurement/efbc:ApplicableLegalBasis[@listName = 'cvd-scope'])           else             true()">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-717) then             exists(cac:TenderingTerms/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/efext:EformsExtension/efac:StrategicProcurement/efbc:ApplicableLegalBasis[@listName = 'cvd-scope'])           else             true()'
Error: Cannot compare xs:boolean to xs:double</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert id="CR-DE-BT-769-Lot" location="/can:ContractAwardNotice/cac:ProcurementProjectLot" test="if ($SUBTYPE = $SUBTYPES-BT-769) then             boolean(normalize-space(cac:TenderingTerms/cbc:MultipleTendersCode))           else             true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if ($SUBTYPE = $SUBTYPES-BT-769) then             boolean(normalize-space(cac:TenderingTerms/cbc:MultipleTendersCode))           else             true()'
Error: Cannot compare xs:boolean to xs:string</svrl:text>
  </svrl:failed-assert>
  <svrl:active-pattern id="codelists" />
  <svrl:fired-rule context="//$ROOT-NODE/cac:ContractingParty/cac:ContractingPartyType/cbc:PartyTypeCode[@listName = 'buyer-legal-type']" />
  <svrl:fired-rule context="//$ROOT-NODE/cac:TenderingProcess/cbc:ProcedureCode" />
  <svrl:fired-rule context="//$ROOT-NODE/cac:TenderingTerms/cac:ProcurementLegislationDocumentReference/cbc:ID" />
  <svrl:active-pattern id="conditional-mandatory" />
  <svrl:fired-rule context="//$ROOT-NODE/cac:ProcurementProjectLot[cbc:ID/@schemeName = 'Lot']/cac:ProcurementProject/cac:ProcurementAdditionalType" />
  <svrl:fired-rule context="//$ROOT-NODE/cac:ProcurementProjectLot[cbc:ID/@schemeName = ('Part', 'Lot', 'LotsGroup')]/cac:ProcurementProject/cbc:Note" />
  <svrl:fired-rule context="//$ROOT-NODE/cac:ProcurementProjectLot[cbc:ID/@schemeName = ('Lot', 'Part')]/cac:TenderingTerms/cac:AwardingTerms/cac:AwardingCriterion/cac:SubordinateAwardingCriterion" />
  <svrl:failed-assert id="BR-DE-23" location="/can:ContractAwardNotice/cac:ProcurementProjectLot/cac:TenderingTerms/cac:AwardingTerms/cac:AwardingCriterion/cac:SubordinateAwardingCriterion" test="if         (normalize-space($AwardCriterionParameter/efbc:ParameterCode/text()) = 'per-exa' and         number(normalize-space($AwardCriterionParameter/efbc:ParameterNumeric/text())) ge 10         )         then           (boolean(normalize-space(cbc:AwardingCriterionTypeCode)) and           boolean(normalize-space(cbc:Name[./@languageID = $MAIN-LANG]))           )         else           true()" role="error">
    <svrl:text>Failed to evaluate XPath expression to a boolean.
Test: 'if         (normalize-space($AwardCriterionParameter/efbc:ParameterCode/text()) = 'per-exa' and         number(normalize-space($AwardCriterionParameter/efbc:ParameterNumeric/text())) ge 10         )         then           (boolean(normalize-space(cbc:AwardingCriterionTypeCode)) and           boolean(normalize-space(cbc:Name[./@languageID = $MAIN-LANG]))           )         else           true()'
Error: A sequence of more than one item is not allowed as the first argument of fn:normalize-space() ("0.4", "0.6") </svrl:text>
  </svrl:failed-assert>
  <svrl:active-pattern id="doe-validation-pattern" />
  <svrl:fired-rule context="//$ROOT-NODE" />
  <svrl:failed-assert location="/can:ContractAwardNotice" test="$BT-05-DATE ge $CURRENT-DATE - xs:dayTimeDuration('P1D')">
    <svrl:text>Date of BT-05= must be less than 1 day in the past. Current date=2024-07-12+02:00. Difference=</svrl:text>
  </svrl:failed-assert>
  <svrl:failed-assert location="/can:ContractAwardNotice" test="$BT-05-DATE le $CURRENT-DATE + xs:dayTimeDuration('P1D')">
    <svrl:text>Date of BT-05= must be less than 1 day in the future. Current date=2024-07-12+02:00. Difference=$CURRENT-DATE + xs:dayTimeDuration('P1D')</svrl:text>
  </svrl:failed-assert>
</svrl:schematron-output>

@gediminasre
Copy link
Author

@phax this SVRL report looks just what we need. Thank you very much!

@phax
Copy link
Owner

phax commented Jul 15, 2024

Great :) Will be part of the next 8.x release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants