Add France schematron ruleset

This commit is contained in:
Zahi YOUSFI
2026-04-10 11:03:37 +02:00
parent 64512f1ead
commit bcfec257b1
5 changed files with 5875 additions and 0 deletions

View File

@@ -192,8 +192,10 @@ public class XMLValidator extends Validator {
boolean isExtended = false;
boolean isXRechnung = false;
String currentZFVersionDir = "ZF_240";
String currentXPZ12VersionDir ="XP_Z12_012";
int mainSchematronSectionErrorTypeCode = 4;
String xsltFilename = null;
boolean runFrenchCiiSchematron = false;
// urn:ferd:CrossIndustryDocument:invoice:1p0:extended,
// urn:ferd:CrossIndustryDocument:invoice:1p0:comfort,
// urn:ferd:CrossIndustryDocument:invoice:1p0:basic,
@@ -213,6 +215,11 @@ public class XMLValidator extends Validator {
} else if (root.getLocalName().equalsIgnoreCase("CrossIndustryInvoice")) { // ZUGFeRD 2.0 or Factur-X
context.setGeneration("2");
final String sellerCountry = getXPathString(doc,
"//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeAgreement']//*[local-name() = 'SellerTradeParty']//*[local-name() = 'PostalTradeAddress']/*[local-name() = 'CountryID']/text()");
final String buyerCountry = getXPathString(doc,
"//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeAgreement']//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'PostalTradeAddress']/*[local-name() = 'CountryID']/text()");
runFrenchCiiSchematron = "FR".equalsIgnoreCase(sellerCountry) && "FR".equalsIgnoreCase(buyerCountry);
isMiniumum = contextProfile.contains("minimum");
isBasic = contextProfile.contains("basic");
@@ -370,6 +377,11 @@ public class XMLValidator extends Validator {
// main schematron validation
validateSchematron(zfXML, xsltFilename, mainSchematronSectionErrorTypeCode, ESeverity.error);
if (runFrenchCiiSchematron) {
String xsltFRFilename = "/xslt/" + currentXPZ12VersionDir + "/20260216_BR-FR-Flux2-Schematron-CII_V1.3.0.xsl";
validateSchematron(zfXML, xsltFRFilename, mainSchematronSectionErrorTypeCode, ESeverity.error);
}
}
if ("CII".equals(context.getFormat()) && ("2".equals(context.getGeneration()))) {
@@ -525,6 +537,16 @@ public class XMLValidator extends Validator {
}
}
private String getXPathString(Document doc, String expression) throws IrrecoverableValidationError {
try {
XPath xpath = XPathFactory.newInstance().newXPath();
String value = (String) xpath.compile(expression).evaluate(doc, XPathConstants.STRING);
return value == null ? "" : value.trim();
} catch (XPathExpressionException e) {
throw new IrrecoverableValidationError(e.getMessage());
}
}
public void validateXR(String xml, ESeverity errorImpact) throws IrrecoverableValidationError {
//Guideline ID=urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_1.2 or