I have a schematron file which is seperated to 3 files. One file contains using codes list, other one contains details and messages which will be fired and other one contains declaration of these rules. I don't have a version
or queryBinding
property on root. So i guess it is a XSLT 1.0. I have used SaxonCS and SchXslt before while running a Xslt 2.0 validation. What do i have to do on this case? I am providing some sample blocks from files below.
File 1
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns=";
xmlns:sch=";
xmlns:sh=";
xmlns:ef=";>
<sch:include href="UBL-TR_Codelist.xml#codes"/>
<sch:include href="UBL-TR_Common_Schematron.xml#abstracts"/>
<sch:ns prefix="sh" uri="; />
<sch:ns prefix="ef" uri="; />
<sch:ns prefix="inv" uri="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" />
<sch:ns prefix="apr" uri="urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2" />
<sch:ns prefix="desp" uri="urn:oasis:names:specification:ubl:schema:xsd:DespatchAdvice-2" />
<sch:ns prefix="recp" uri="urn:oasis:names:specification:ubl:schema:xsd:ReceiptAdvice-2" />
<sch:ns prefix="cac" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" />
<sch:ns prefix="cbc" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" />
<sch:ns prefix="ext" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" />
<sch:ns prefix="ds" uri="; />
<sch:ns prefix="xades" uri=".3.2#" />
<sch:ns prefix="hr" uri="; />
<sch:ns prefix="oa" uri="; />
<sch:ns prefix="xsi" uri="; />
<let name="envelopeType" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:DocumentIdentification/sh:Type"/>
<let name="senderId" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:Sender/sh:ContactInformation[sh:ContactTypeIdentifier = 'VKN_TCKN']/sh:Contact"/>
<let name="senderAlias" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:Sender/sh:Identifier"/>
<let name="receiverId" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:Receiver/sh:ContactInformation[sh:ContactTypeIdentifier = 'VKN_TCKN']/sh:Contact"/>
<let name="receiverAlias" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:Receiver/sh:Identifier"/>
<let name="responseCode" value="//apr:ApplicationResponse/cac:DocumentResponse/cac:Response/cbc:ResponseCode" />
<!-- Invoice -->
<sch:pattern id="invoice">
<sch:rule context="inv:Invoice">
<sch:extends rule="UBLVersionIDCheck"/>
<sch:extends rule="CustomizationIDCheck"/>
<sch:extends rule="ProfileIDCheck"/>
<sch:extends rule="InvoiceIDCheck"/>
<sch:extends rule="CopyIndicatorCheck"/>
<!--<sch:extends rule="TimeCheck"/>-->
<sch:extends rule="InvoiceTypeCodeCheck"/>
<sch:extends rule="CurrencyCodeCheck"/>
<!-- <sch:extends rule="URI2IDCheck"/> -->
<sch:extends rule="SignatureCountCheck"/>
<sch:extends rule="GeneralWithholdingTaxTotalCheck"/>
<sch:extends rule="DeliveryCodeCheck"/>
<sch:extends rule="TaxRepresentativePartyCheck"/>
<sch:extends rule="HKSInvioceCheck"/>
<sch:extends rule="IADEInvioceCheck"/>
<sch:extends rule="IlacTibbiCihazInvoiceTypeCodeCheck"/>
</sch:rule>
</sch:pattern>
</sch:schema>
File 2
<sch:schema xmlns=";
xmlns:sch=";>
<sch:pattern name="AbstractRules" id="abstracts">
<sch:p>Pattern for storing abstract rules</sch:p>
<!-- Rule to validate UBLVersionID -->
<sch:rule abstract="true" id="UBLVersionIDCheck">
<sch:assert test="cbc:UBLVersionID = '2.1'">Geçersiz cbc:UBLVersionID elemanı değeri : '<sch:value-of select="cbc:UBLVersionID"/>'. cbc:UBLVersionID değeri '2.1' olmalıdır.</sch:assert>
</sch:rule>
<!-- Rule to validate CustomizationID -->
<sch:rule abstract="true" id="CustomizationIDCheck">
<sch:assert test="cbc:CustomizationID = 'TR1.2' or cbc:CustomizationID = 'TR1.2.1'">Geçersiz cbc:CustomizationID elemanı değeri : '<sch:value-of select="cbc:CustomizationID"/>' cbc:CustomizationID elemanı değeri 'TR1.2' veya 'TR1.2.1' olmalıdır.</sch:assert>
</sch:rule>
<!-- Rule to validate ProfileID -->
<sch:rule abstract="true" id="ProfileIDCheck">
<sch:assert test="not($type = 'efatura' or $type = '' or not($type)) or contains($ProfileIDType, concat(',',cbc:ProfileID,','))">Geçersiz cbc:ProfileID elemanı değeri : '<sch:value-of select="cbc:ProfileID"/>'. Geçerli cbc:ProfileID değerleri için ProfileIDType listesine bakınız.</sch:assert>
<sch:assert test="not($type = 'earchive') or contains($ProfileIDTypeEarchive, concat(',',cbc:ProfileID,','))">Geçersiz cbc:ProfileID elemanı değeri : '<sch:value-of select="cbc:ProfileID"/>'. Geçerli cbc:ProfileID değerleri için ProfileIDTypeEarchive listesine bakınız.</sch:assert>
<sch:assert test="not($type = 'goruntuleme') or contains($ProfileIDTypeGoruntuleme, concat(',',cbc:ProfileID,','))">Geçersiz cbc:ProfileID elemanı değeri : '<sch:value-of select="cbc:ProfileID"/>'. Geçerli cbc:ProfileID değerleri için ProfileIDTypeGoruntuleme listesine bakınız.</sch:assert>
<sch:assert test="not(@xsi:schemaLocation) or contains(@xsi:schemaLocation,'UBL-Invoice-2.1.xsd')">Invoice alanın xsi:schemaLocation özeliği 'UBL-Invoice-2.1.xsd' olmalıdır</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
Source Code :
var fileName = Path.GetFileName(inputXml);
var inputSch = "E:/aa/schematrontest/UBL-TR_Main_Schematron.xml";
string schxsltSvrlXsltResource = @"SchematronSchxsltSaxonCSValidator\schxslt_xslt1\iso_svrl_for_xslt1.xsl";
var schxsltResourceUri = UriUtils.GetLocationUri(schxsltSvrlXsltResource, Assembly.GetExecutingAssembly());
var resolver = new Resolver();
var settings = new XmlReaderSettings() { XmlResolver = resolver };
var processor = new Processor(true);
var xsltCompiler = processor.NewXsltCompiler();
using var schxsltReader = XmlReader.Create(schxsltResourceUri.AbsoluteUri, settings);
var transformer = xsltCompiler.Compile(schxsltReader).Load30();
var compiledSchematron = new XdmDestination();
compiledSchematron.BaseUri = new Uri(new FileInfo(inputSch).FullName);
using var schemaStream = File.OpenRead(inputSch);
transformer.Transform(schemaStream, compiledSchematron);
var xsltCompiler2 = processor.NewXsltCompiler();
var schematronValidator = xsltCompiler2.Compile(compiledSchematron.XdmNode).Load30();
var svrlResult = new DomDestination();
using var instanceStream = File.OpenRead(inputXml);
schematronValidator.Transform(instanceStream, new Uri(new FileInfo(inputXml).FullName), svrlResult);
List<ErrorModel> errors = new List<ErrorModel>();
var failedNodes = svrlResult.XmlDocument.GetElementsByTagName("svrl:failed-assert");
I have a schematron file which is seperated to 3 files. One file contains using codes list, other one contains details and messages which will be fired and other one contains declaration of these rules. I don't have a version
or queryBinding
property on root. So i guess it is a XSLT 1.0. I have used SaxonCS and SchXslt before while running a Xslt 2.0 validation. What do i have to do on this case? I am providing some sample blocks from files below.
File 1
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns="http://purl.oclc./dsdl/schematron"
xmlns:sch="http://purl.oclc./dsdl/schematron"
xmlns:sh="http://www.unece./cefact/namespaces/StandardBusinessDocumentHeader"
xmlns:ef="http://www.efatura.gov.tr/envelope-namespace">
<sch:include href="UBL-TR_Codelist.xml#codes"/>
<sch:include href="UBL-TR_Common_Schematron.xml#abstracts"/>
<sch:ns prefix="sh" uri="http://www.unece./cefact/namespaces/StandardBusinessDocumentHeader" />
<sch:ns prefix="ef" uri="http://www.efatura.gov.tr/package-namespace" />
<sch:ns prefix="inv" uri="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" />
<sch:ns prefix="apr" uri="urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2" />
<sch:ns prefix="desp" uri="urn:oasis:names:specification:ubl:schema:xsd:DespatchAdvice-2" />
<sch:ns prefix="recp" uri="urn:oasis:names:specification:ubl:schema:xsd:ReceiptAdvice-2" />
<sch:ns prefix="cac" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" />
<sch:ns prefix="cbc" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" />
<sch:ns prefix="ext" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" />
<sch:ns prefix="ds" uri="http://www.w3./2000/09/xmldsig#" />
<sch:ns prefix="xades" uri="http://uri.etsi./01903/v1.3.2#" />
<sch:ns prefix="hr" uri="http://www.hr-xml./3" />
<sch:ns prefix="oa" uri="http://www.openapplications./oagis/9" />
<sch:ns prefix="xsi" uri="http://www.w3./2001/XMLSchema-instance" />
<let name="envelopeType" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:DocumentIdentification/sh:Type"/>
<let name="senderId" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:Sender/sh:ContactInformation[sh:ContactTypeIdentifier = 'VKN_TCKN']/sh:Contact"/>
<let name="senderAlias" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:Sender/sh:Identifier"/>
<let name="receiverId" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:Receiver/sh:ContactInformation[sh:ContactTypeIdentifier = 'VKN_TCKN']/sh:Contact"/>
<let name="receiverAlias" value="/sh:StandardBusinessDocument/sh:StandardBusinessDocumentHeader/sh:Receiver/sh:Identifier"/>
<let name="responseCode" value="//apr:ApplicationResponse/cac:DocumentResponse/cac:Response/cbc:ResponseCode" />
<!-- Invoice -->
<sch:pattern id="invoice">
<sch:rule context="inv:Invoice">
<sch:extends rule="UBLVersionIDCheck"/>
<sch:extends rule="CustomizationIDCheck"/>
<sch:extends rule="ProfileIDCheck"/>
<sch:extends rule="InvoiceIDCheck"/>
<sch:extends rule="CopyIndicatorCheck"/>
<!--<sch:extends rule="TimeCheck"/>-->
<sch:extends rule="InvoiceTypeCodeCheck"/>
<sch:extends rule="CurrencyCodeCheck"/>
<!-- <sch:extends rule="URI2IDCheck"/> -->
<sch:extends rule="SignatureCountCheck"/>
<sch:extends rule="GeneralWithholdingTaxTotalCheck"/>
<sch:extends rule="DeliveryCodeCheck"/>
<sch:extends rule="TaxRepresentativePartyCheck"/>
<sch:extends rule="HKSInvioceCheck"/>
<sch:extends rule="IADEInvioceCheck"/>
<sch:extends rule="IlacTibbiCihazInvoiceTypeCodeCheck"/>
</sch:rule>
</sch:pattern>
</sch:schema>
File 2
<sch:schema xmlns="http://purl.oclc./dsdl/schematron"
xmlns:sch="http://purl.oclc./dsdl/schematron">
<sch:pattern name="AbstractRules" id="abstracts">
<sch:p>Pattern for storing abstract rules</sch:p>
<!-- Rule to validate UBLVersionID -->
<sch:rule abstract="true" id="UBLVersionIDCheck">
<sch:assert test="cbc:UBLVersionID = '2.1'">Geçersiz cbc:UBLVersionID elemanı değeri : '<sch:value-of select="cbc:UBLVersionID"/>'. cbc:UBLVersionID değeri '2.1' olmalıdır.</sch:assert>
</sch:rule>
<!-- Rule to validate CustomizationID -->
<sch:rule abstract="true" id="CustomizationIDCheck">
<sch:assert test="cbc:CustomizationID = 'TR1.2' or cbc:CustomizationID = 'TR1.2.1'">Geçersiz cbc:CustomizationID elemanı değeri : '<sch:value-of select="cbc:CustomizationID"/>' cbc:CustomizationID elemanı değeri 'TR1.2' veya 'TR1.2.1' olmalıdır.</sch:assert>
</sch:rule>
<!-- Rule to validate ProfileID -->
<sch:rule abstract="true" id="ProfileIDCheck">
<sch:assert test="not($type = 'efatura' or $type = '' or not($type)) or contains($ProfileIDType, concat(',',cbc:ProfileID,','))">Geçersiz cbc:ProfileID elemanı değeri : '<sch:value-of select="cbc:ProfileID"/>'. Geçerli cbc:ProfileID değerleri için ProfileIDType listesine bakınız.</sch:assert>
<sch:assert test="not($type = 'earchive') or contains($ProfileIDTypeEarchive, concat(',',cbc:ProfileID,','))">Geçersiz cbc:ProfileID elemanı değeri : '<sch:value-of select="cbc:ProfileID"/>'. Geçerli cbc:ProfileID değerleri için ProfileIDTypeEarchive listesine bakınız.</sch:assert>
<sch:assert test="not($type = 'goruntuleme') or contains($ProfileIDTypeGoruntuleme, concat(',',cbc:ProfileID,','))">Geçersiz cbc:ProfileID elemanı değeri : '<sch:value-of select="cbc:ProfileID"/>'. Geçerli cbc:ProfileID değerleri için ProfileIDTypeGoruntuleme listesine bakınız.</sch:assert>
<sch:assert test="not(@xsi:schemaLocation) or contains(@xsi:schemaLocation,'UBL-Invoice-2.1.xsd')">Invoice alanın xsi:schemaLocation özeliği 'UBL-Invoice-2.1.xsd' olmalıdır</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
Source Code :
var fileName = Path.GetFileName(inputXml);
var inputSch = "E:/aa/schematrontest/UBL-TR_Main_Schematron.xml";
string schxsltSvrlXsltResource = @"SchematronSchxsltSaxonCSValidator\schxslt_xslt1\iso_svrl_for_xslt1.xsl";
var schxsltResourceUri = UriUtils.GetLocationUri(schxsltSvrlXsltResource, Assembly.GetExecutingAssembly());
var resolver = new Resolver();
var settings = new XmlReaderSettings() { XmlResolver = resolver };
var processor = new Processor(true);
var xsltCompiler = processor.NewXsltCompiler();
using var schxsltReader = XmlReader.Create(schxsltResourceUri.AbsoluteUri, settings);
var transformer = xsltCompiler.Compile(schxsltReader).Load30();
var compiledSchematron = new XdmDestination();
compiledSchematron.BaseUri = new Uri(new FileInfo(inputSch).FullName);
using var schemaStream = File.OpenRead(inputSch);
transformer.Transform(schemaStream, compiledSchematron);
var xsltCompiler2 = processor.NewXsltCompiler();
var schematronValidator = xsltCompiler2.Compile(compiledSchematron.XdmNode).Load30();
var svrlResult = new DomDestination();
using var instanceStream = File.OpenRead(inputXml);
schematronValidator.Transform(instanceStream, new Uri(new FileInfo(inputXml).FullName), svrlResult);
List<ErrorModel> errors = new List<ErrorModel>();
var failedNodes = svrlResult.XmlDocument.GetElementsByTagName("svrl:failed-assert");
Using the Schematron "skeleton" implementation, you need to resolve the includes and the abstracts before converting it to an XSL file that can be used to execute validation on your XML document. That's what Oxygen XML is doing behind the scenes. See the instructions in https://github/Schematron/schematron/blob/master/trunk/schematron/code/readme.txt, quoted here:
First, preprocess your Schematron schema with iso_dsdl_include.xsl. This is a macro processor to assemble the schema from various parts. If your schema is not in separate parts, you can skip this stage. This stage also generates error messages for some common XPath syntax problems.
Second, preprocess the output from stage 1 with iso_abstract_expand.xsl. This is a macro processor to convert abstract patterns to real patterns. If your schema does not use abstract patterns, you can skip this stage.
Third, compile the Schematron schema into an XSLT script. This will typically use iso_svrl_for_xslt1.xsl or iso_svrl_for_xslt2.xsl (which in turn invoke iso_schematron_skeleton_for_xslt1.xsl or iso_schematron_skeleton_for_saxon.xsl) However, other "meta-stylesheets" are also in common use; the principle of operation is the same. If your schema uses Schematron phases, supply these as command line/invocation parameters to this process.
Fourth, run the script generated by stage 3 against the document being validated. If you are using the SVRL script, then the output of validation will be an XML document. If your schema uses Schematron parameters, supply these as command line/invocation parameters to this process.