diff --git a/library/pom.xml b/library/pom.xml index 13a01a10..860e4526 100644 --- a/library/pom.xml +++ b/library/pom.xml @@ -11,8 +11,8 @@ library 2.5.5-SNAPSHOT jar - Library to write, read and validate e-invoices (Factur-X, ZUGFeRD and to a limited extend XRechnung/CII). - The Mustang project is a java library to read, write and validate Factur-X/ZUGFeRD meta data inside your invoice PDFs. To write files, a provided PDF/A will be combined with generated or provided XML. + Library to write, read and validate e-invoices (Factur-X, ZUGFeRD, Order-X, XRechnung/CII) + FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT Cross Industry Invoice based formats Factur-X/ZUGFeRD, XRechnung and Order-X in your invoice PDFs. http://www.mustangproject.org/ @@ -105,12 +105,6 @@ 2.3.3 - - com.helger - ph-schematron - 5.0.4 - test - org.xmlunit xmlunit-core diff --git a/validator/pom.xml b/validator/pom.xml index f6c5dff9..5307f63d 100644 --- a/validator/pom.xml +++ b/validator/pom.xml @@ -78,9 +78,9 @@ - com.helger - ph-schematron - 5.6.0 + com.helger.schematron + ph-schematron-xslt + 6.3.3 com.helger @@ -158,8 +158,8 @@ - 8 - 8 + 11 + 11 diff --git a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java index 46b7e541..db375935 100644 --- a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java @@ -6,6 +6,7 @@ import java.io.StringReader; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.Calendar; import java.util.List; @@ -13,12 +14,13 @@ import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.stream.StreamSource; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathFactory; +import javax.xml.xpath.*; +import com.helger.schematron.svrl.SVRLMarshaller; import com.helger.schematron.svrl.jaxb.ActivePattern; +import com.helger.schematron.xslt.SchematronResourceXSLTCache; +import org.mustangproject.Contact; +import org.mustangproject.SchemedID; import org.mustangproject.XMLTools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -392,6 +394,7 @@ public class XMLValidator extends Validator { public void validateSchematron(String xml, String xsltFilename, int section, ESeverity severity) throws IrrecoverableValidationError { ISchematronResource aResSCH = null; aResSCH = SchematronResourceXSLT.fromClassPath(xsltFilename); + if (aResSCH != null) { if (!aResSCH.isValidSchematron()) { throw new IllegalArgumentException(xsltFilename + " is invalid Schematron!"); @@ -404,25 +407,68 @@ public class XMLValidator extends Validator { } catch (final Exception e) { throw new IrrecoverableValidationError(e.getMessage()); } + Document SVRLReport=new SVRLMarshaller().getAsDocument(sout); + XPath xPath = XPathFactory.newInstance().newXPath(); + String expression = "//*[local-name() = 'failed-assert']"; + NodeList failedAsserts = null; + try { + failedAsserts = (NodeList) xPath.compile(expression).evaluate(SVRLReport, XPathConstants.NODESET); - final List failedAsserts = sout.getActivePatternAndFiredRuleAndFailedAssert(); - if (failedAsserts.size() > 0) { - for (final Object object : failedAsserts) { - if (object instanceof FailedAssert) { + String thisFailText=""; + String thisFailID=""; + String thisFailTest=""; + String thisFailLocation=""; + if (failedAsserts.getLength() > 0) { - final FailedAssert failedAssert = (FailedAssert) object; - LOGGER.info("FailedAssert ", failedAssert); + for (int nodeIndex = 0; nodeIndex < failedAsserts.getLength(); nodeIndex++) { + //nodes.item(i).getTextContent())) { + Node currentFailNode = failedAsserts.item(nodeIndex); + if (currentFailNode.getAttributes().getNamedItem("id") != null) { + thisFailID=" [ID "+currentFailNode.getAttributes().getNamedItem("id").getNodeValue()+"]"; + } + if (currentFailNode.getAttributes().getNamedItem("test") != null) { + thisFailTest=currentFailNode.getAttributes().getNamedItem("test").getNodeValue(); + } + if (currentFailNode.getAttributes().getNamedItem("location") != null) { + thisFailLocation=currentFailNode.getAttributes().getNamedItem("location").getNodeValue(); + } - context.addResultItem(new ValidationResultItem(severity, SVRLHelper.getAsString(failedAssert.getText())+" (From "+xsltFilename+")") - .setLocation(failedAssert.getLocation()).setCriterion(failedAssert.getTest()).setSection(section) - .setPart(EPart.fx)); - failedRules++; - } else if (object instanceof FiredRule) { - firedRules++; + NodeList failChilds = currentFailNode.getChildNodes(); + for (int failChildIndex = 0; failChildIndex < failChilds.getLength(); failChildIndex++) { + if (failChilds.item(failChildIndex).getLocalName() != null) { + + if (failChilds.item(failChildIndex).getLocalName().equals("text")) { + // if (itemChilds.item(failChildIndex).getAttributes().getNamedItem("schemeID") != null) { + thisFailText=failChilds.item(failChildIndex).getTextContent(); + + } + } + } } + + LOGGER.info("FailedAssert ", thisFailText); + + context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailID + " from " + xsltFilename + ")") + .setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section) + .setPart(EPart.fx)); + failedRules++; + + } + } catch (XPathExpressionException e) { + LOGGER.error(e.getMessage(), e); } + expression = "//*[local-name() = 'fired-rule']"; + NodeList firedAsserts = null; + try { + firedAsserts = (NodeList) xPath.compile(expression).evaluate(SVRLReport, XPathConstants.NODESET); + firedRules=firedAsserts.getLength(); + } catch (XPathExpressionException e) { + LOGGER.error(e.getMessage(), e); + } + + if (firedRules == 0) { context.addResultItem(new ValidationResultItem(ESeverity.error, "No rules matched, XML to minimal?").setSection(26) .setPart(EPart.fx));