mirror of
https://github.com/itplr-kosit/validator.git
synced 2026-05-25 16:55:39 +00:00
Merge branch 'master' into 48-documentation-and-semantic-defintion-of-accpetmatch-functionality
This commit is contained in:
commit
a670b227ed
24 changed files with 381 additions and 421 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -36,3 +36,6 @@ src/generated
|
|||
.settings
|
||||
.vscode
|
||||
*.code-workspace
|
||||
|
||||
# Testing stuff
|
||||
xrechnung
|
||||
|
|
|
|||
24
CHANGELOG.md
24
CHANGELOG.md
|
|
@ -5,16 +5,36 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
|
||||
## next version (unreleased)
|
||||
|
||||
# Added
|
||||
### Added
|
||||
|
||||
- Support java.xml.transform.Source/java.xml.transform.StreamSource as Input
|
||||
|
||||
# Changed
|
||||
### Changed
|
||||
|
||||
- Inputs are NOT read into memory (e.g. Byte-Array) prior processing within the validator. This reduces memory consumption.
|
||||
|
||||
## UNRELEASED
|
||||
### Fixed
|
||||
- Validator was creating invalid createReportInput xml in case of no scenrio match
|
||||
|
||||
## 1.2.0
|
||||
### Added
|
||||
|
||||
- Provide access to schematron result through [Result.java](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/Result.java)
|
||||
- *Result#getFailedAsserts()* returns a list of failed asserts found by schematron
|
||||
- *Result#isSchematronValid()* convinience access to evaluate whether schematron was processed without any *FailedAsserts*
|
||||
### Changed
|
||||
|
||||
- *Result#getAcceptRecommendation()* does not _only_ work when _acceptMatch_ is configured in the scenario
|
||||
- schema correctness is a precondition, if the checked instance is not valid, this evaluates to _REJECTED_
|
||||
- if _acceptMatch_ is configured, the result is based on the boolean result of the xpath expression evaluated against the generated report
|
||||
- if *no* _acceptMatch_ is configured, the result is based on evaluation of schema and schematron correctness
|
||||
- _UNDEFINED_ is only returned, when processing is stopped somehow
|
||||
- *Result#isAcceptable()* can now evaluate to true, when no _acceptMatch_ is configured (see above)
|
||||
|
||||
## 1.1.3
|
||||
|
||||
### Fixed
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ java -jar validationtool-<version>-standalone.jar --help
|
|||
|
||||
A concrete example with a specific validator configuration can be found on [GitHub](https://github.com/itplr-kosit/validator-configuration-xrechnung)
|
||||
|
||||
### Application User Interface (API / embedded usage)
|
||||
|
||||
The validator can also be used in own Java Applications via the API. Details can be [found here](./docs/api.md).
|
||||
|
||||
### Daemon-Mode
|
||||
|
||||
You can also start the validator as an HTTP-Server. Just start it in _Daemon-Mode_ with the `-D` option.
|
||||
|
|
@ -86,6 +90,4 @@ You can HTTP-POST to `/` and the response will return the report document as de
|
|||
|
||||
Additionally there is the GET `/health` endpoint which can be used by monitoring systems.
|
||||
|
||||
### Application User Interface (embedded usage)
|
||||
|
||||
The validator can also be used in own Java Applications via the API. Details can be [found here](./docs/api.md).
|
||||
|
|
|
|||
40
docs/api.md
40
docs/api.md
|
|
@ -4,7 +4,8 @@ The Validator offers an API which allows you to integrate Validator in your own
|
|||
|
||||
## Dependency Management
|
||||
|
||||
Currently, we *do not* deploy to Maven Central or similar. Hence you need to build and optionally deploy the Validator artifacts to your own shared repository (see for example [Maven Documentation](https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html)).
|
||||
Currently, we *do not* deploy to Maven Central or similar. Hence you need to build and optionally deploy the Validator artifacts to your own
|
||||
shared (or local) repository (see for example [Maven Documentation](https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html)).
|
||||
|
||||
### Maven
|
||||
|
||||
|
|
@ -28,7 +29,8 @@ dependencies {
|
|||
|
||||
## Usage
|
||||
|
||||
Prerequisite for use is a valid [scenario definition](configurations.md) and the a folder with all necessary artifacts for validation (repository) either on the filesystem or on the classpath.
|
||||
Prerequisite for use is a valid [scenario definition](configurations.md) and the a folder with all necessary artifacts for validation
|
||||
(repository) either on the filesystem or on the classpath.
|
||||
|
||||
The following example demonstrates loading scenario.xml and whole configuration from classpath and validating one XML document:
|
||||
|
||||
|
|
@ -81,14 +83,19 @@ public class StandardExample {
|
|||
}
|
||||
```
|
||||
|
||||
The `Result` interface has more methods to retrieve details about XSD validation errors and Schematron messages.
|
||||
The `Result` interface has convenience methods to retrieve details about XSD validation errors and Schematron messages and other processing results. See
|
||||
[Result.java](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/Result.java) for details.
|
||||
|
||||
Initializing all XML artifacts and XSLT-executables is expensive. The `Check` instance is *threadsafe* and keeps all artifacts. Therefore, we recommend the re-use of an `Check` instance.
|
||||
|
||||
* Batch use is serial and *not parallel*
|
||||
Initializing all XML artifacts and XSLT-executables is expensive. The `Check` instance is *threadsafe* and keeps all artifacts. Therefore,
|
||||
we recommend the re-use of an `Check` instance.
|
||||
|
||||
The only input `de.kosit.validationtool.api.Input` which can be created by various methods of `de.kosit.validationtool.api.InputFactory`.
|
||||
The `InputFactory` calculates a hash sum for each Input which is also written to the Report. _SHA-256_ from the JDK is the default algorithm. It can be changed using the `read`-methods of `InputFactory`.
|
||||
The `InputFactory` calculates a hash sum for each Input which is also written to the Report. _SHA-256_ from the JDK is the default algorithm.
|
||||
It can be changed using the `read`-methods of `InputFactory`.
|
||||
|
||||
The main interface [Check.java](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/Check.java)
|
||||
allows using a batch interface (processing list of [Inputs](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/Input.java)).
|
||||
However, there is no parallel processing implemented at the moment.
|
||||
|
||||
## Accept Recommendation and Accept Match
|
||||
|
||||
|
|
@ -96,14 +103,21 @@ A tri-state Object `AcceptRecommendation` can be retrieved from the `Result` usi
|
|||
|
||||
The three defined states are:
|
||||
|
||||
1. `UNDEFINED` i.e. the evaluation of the overall validation could not be computed.
|
||||
2. `ACCEPTABLE` i.e. the recommendation is to accept input based on the evaluation of the overall validation.
|
||||
3. `REJECT` i.e. the recommendation is to reject input based on the evaluation of the overall validation.
|
||||
1. `ACCEPTABLE` i.e. the recommendation is to accept input based on the evaluation of the overall validation.
|
||||
1. `REJECT` i.e. the recommendation is to reject input based on the evaluation of the overall validation.
|
||||
1. `UNDEFINED` i.e. the evaluation of the overall validation could not be computed (overall processing is incomplete)
|
||||
|
||||
By default it is `UNDEFINED`.
|
||||
The accept recommendation is based on either:
|
||||
|
||||
1. schema and schematron validation results
|
||||
1. if configured based on _acceptMatch_ configuration of the scenario (see below)
|
||||
|
||||
### Accept Match in Scenario Configuration
|
||||
|
||||
For your own configuration you can add an `acceptMatch` element in each scenario. It can contain in XPATH expression over your own defined `Report` to compute a boolean. An XPATH expression evaluating to true will lead to an `ACCEPTABLE` amd otherwise to a `REJECT` recommendation.
|
||||
For your own configuration you can add an `acceptMatch` element in each scenario. It can contain in XPATH expression over your own
|
||||
defined `Report` to compute a boolean value. An XPATH expression evaluating to true will lead to an `ACCEPTABLE` and otherwise to a `REJECT`
|
||||
recommendation.
|
||||
|
||||
This allows to have own control over what validation result is to be considered acceptable for your own application context.
|
||||
This allows to have control over what validation result is to be considered _acceptable_ for your own application context. E.g. you can
|
||||
overrule schematron validation errors with _acceptMatch_ configuration and consider certain errors as _acceptable_. Nevertheless you can *not*
|
||||
overrule schema errors with accept match.
|
||||
|
|
|
|||
2
pom.xml
2
pom.xml
|
|
@ -6,7 +6,7 @@
|
|||
<name>KoSIT XML Prüftool Implementierung</name>
|
||||
|
||||
<groupId>de.kosit</groupId>
|
||||
<version>1.2.0-SNAPSHOT</version>
|
||||
<version>1.3.0-SNAPSHOT</version>
|
||||
|
||||
<artifactId>validationtool</artifactId>
|
||||
<description>KoSIT XML Validator against XSD and Schematron based on defined scenarios.</description>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package de.kosit.validationtool.api;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.oclc.purl.dsdl.svrl.FailedAssert;
|
||||
import org.oclc.purl.dsdl.svrl.SchematronOutput;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
|
|
@ -69,6 +70,13 @@ public interface Result {
|
|||
*/
|
||||
List<SchematronOutput> getSchematronResult();
|
||||
|
||||
/**
|
||||
* Returns {@link org.oclc.purl.dsdl.svrl.FailedAssert FailedAsserts} of a schematron evaluation.
|
||||
*
|
||||
* @return list of {@link org.oclc.purl.dsdl.svrl.FailedAssert FailedAsserts}, if any, empty list otherwise
|
||||
*/
|
||||
List<FailedAssert> getFailedAsserts();
|
||||
|
||||
/**
|
||||
* Liefert ein true, wenn keine Schema-Violations vorhanden sind.
|
||||
*
|
||||
|
|
@ -82,4 +90,11 @@ public interface Result {
|
|||
* @return true wenn well-formed
|
||||
*/
|
||||
boolean isWellformed();
|
||||
|
||||
/**
|
||||
* Returns true, if schematron has been checked and the result does not contain any {@link FailedAssert FailedAsserts}.
|
||||
*
|
||||
* @return true, if valid
|
||||
*/
|
||||
boolean isSchematronValid();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,12 +127,19 @@ public class DefaultResult implements Result {
|
|||
*
|
||||
* @return die {@link FailedAssert}
|
||||
*/
|
||||
@Override
|
||||
public List<FailedAssert> getFailedAsserts() {
|
||||
return filterSchematronResult(FailedAssert.class);
|
||||
}
|
||||
|
||||
private <T> List<T> filterSchematronResult(final Class<T> type) {
|
||||
return getSchematronResult().stream().filter(type::isInstance).map(type::cast).collect(Collectors.toList());
|
||||
return getSchematronResult() != null
|
||||
? getSchematronResult().stream().filter(type::isInstance).map(type::cast).collect(Collectors.toList())
|
||||
: Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSchematronValid() {
|
||||
return getSchematronResult() != null && getFailedAsserts().isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ public class ScenarioRepository {
|
|||
|
||||
private ScenarioType createFallback() {
|
||||
final ScenarioType t = new ScenarioType();
|
||||
t.setFallback(true);
|
||||
t.setName("Fallback-Scenario");
|
||||
t.setMatch("count(/)<0");
|
||||
final CreateReportType reportType = new CreateReportType();
|
||||
|
|
|
|||
|
|
@ -70,6 +70,11 @@ public abstract class BaseScenario {
|
|||
private ResourceType resourceType;
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean fallback;
|
||||
|
||||
private XPathExecutable matchExecutable;
|
||||
|
||||
private XPathExecutable acceptExecutable;
|
||||
|
|
|
|||
|
|
@ -2,15 +2,19 @@ package de.kosit.validationtool.impl.tasks;
|
|||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import org.oclc.purl.dsdl.svrl.FailedAssert;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import de.kosit.validationtool.api.AcceptRecommendation;
|
||||
|
||||
import net.sf.saxon.s9api.SaxonApiException;
|
||||
import net.sf.saxon.s9api.XPathSelector;
|
||||
|
||||
/**
|
||||
* Berechnet die Akzeptanz-Empfehlung gemäß konfigurierten 'acceptMatch' des aktuellen Szenarios.
|
||||
* Computes a {@link AcceptRecommendation} for this instance. This is either based on an 'acceptMatch'-configuration of
|
||||
* the active scenario or based on overall evaluation about schema and semantic (schematron) correctness of the
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
|
|
@ -20,23 +24,49 @@ public class ComputeAcceptanceAction implements CheckAction {
|
|||
|
||||
@Override
|
||||
public void check(final Bag results) {
|
||||
if (preCondtionsMatch(results)) {
|
||||
final String acceptMatch = results.getScenarioSelectionResult().getObject().getAcceptMatch();
|
||||
if (isNotBlank(acceptMatch)) {
|
||||
if (results.getSchemaValidationResult().isValid() && isNotBlank(acceptMatch)) {
|
||||
evaluateAcceptanceMatch(results);
|
||||
} else {
|
||||
evaluateSchemaAndSchematron(results);
|
||||
}
|
||||
} else {
|
||||
results.setAcceptStatus(AcceptRecommendation.REJECT);
|
||||
}
|
||||
}
|
||||
|
||||
private void evaluateSchemaAndSchematron(final Bag results) {
|
||||
if (results.getSchemaValidationResult().isValid() && isSchematronValid(results)) {
|
||||
results.setAcceptStatus(AcceptRecommendation.ACCEPTABLE);
|
||||
} else {
|
||||
results.setAcceptStatus(AcceptRecommendation.REJECT);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSchematronValid(final Bag results) {
|
||||
return !hasSchematronErrors(results);
|
||||
}
|
||||
|
||||
private boolean hasSchematronErrors(final Bag results) {
|
||||
return results.getReportInput().getValidationResultsSchematron().stream().map(e -> e.getResults().getSchematronOutput())
|
||||
.flatMap(e -> e.getActivePatternAndFiredRuleAndFailedAssert().stream()).anyMatch(FailedAssert.class::isInstance);
|
||||
}
|
||||
|
||||
private static void evaluateAcceptanceMatch(final Bag results) {
|
||||
try {
|
||||
|
||||
final XPathSelector selector = results.getScenarioSelectionResult().getObject().getAcceptSelector();
|
||||
selector.setContextItem(results.getReport());
|
||||
results.setAcceptStatus(selector.effectiveBooleanValue() ? AcceptRecommendation.ACCEPTABLE : AcceptRecommendation.REJECT);
|
||||
} catch (final Exception e) {
|
||||
log.error("Fehler bei Evaluierung des Accept-Status: {}", e.getMessage(), e);
|
||||
}
|
||||
} catch (final SaxonApiException e) {
|
||||
final String msg = "Error evaluating accept recommendation: %s";
|
||||
log.error(msg);
|
||||
results.addProcessingError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSkipped(final Bag results) {
|
||||
return results.getReport() == null;
|
||||
private static boolean preCondtionsMatch(final Bag results) {
|
||||
return results.getReport() != null && results.getSchemaValidationResult() != null && results.getScenarioSelectionResult() != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
package de.kosit.validationtool.impl.tasks;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import de.kosit.validationtool.impl.ScenarioRepository;
|
||||
import de.kosit.validationtool.impl.model.Result;
|
||||
|
|
@ -35,6 +36,7 @@ import net.sf.saxon.s9api.XdmNode;
|
|||
* @author Andreas Penski
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class ScenarioSelectionAction implements CheckAction {
|
||||
|
||||
private final ScenarioRepository repository;
|
||||
|
|
@ -47,16 +49,21 @@ public class ScenarioSelectionAction implements CheckAction {
|
|||
if (results.getParserResult().isValid()) {
|
||||
scenarioTypeResult = determineScenario(results.getParserResult().getObject());
|
||||
} else {
|
||||
scenarioTypeResult = new Result<>(repository.getFallbackScenario());
|
||||
scenarioTypeResult = new Result<>(this.repository.getFallbackScenario());
|
||||
}
|
||||
results.setScenarioSelectionResult(scenarioTypeResult);
|
||||
if (!scenarioTypeResult.getObject().isFallback()) {
|
||||
report.setScenario(scenarioTypeResult.getObject());
|
||||
log.info("Schenario {} identified for {}", scenarioTypeResult.getObject().getName(), results.getInput().getName());
|
||||
} else {
|
||||
log.error("No valid schenario configuration found for {}", results.getInput().getName());
|
||||
}
|
||||
}
|
||||
|
||||
private Result<ScenarioType, String> determineScenario(final XdmNode document) {
|
||||
final Result<ScenarioType, String> result = this.repository.selectScenario(document);
|
||||
if (result.isInvalid()) {
|
||||
return new Result<>(repository.getFallbackScenario());
|
||||
return new Result<>(this.repository.getFallbackScenario());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ public class CommandlineApplicationTest {
|
|||
final String[] args = new String[] { "-s", Paths.get(Simple.SCENARIOS).toString(), "-o", this.output.toString(), "-r",
|
||||
Paths.get(Simple.REPOSITORY).toString(), Paths.get(Simple.EXAMPLES).toString() };
|
||||
CommandLineApplication.mainProgram(args);
|
||||
assertThat(this.commandLine.getErrorOutput()).contains("Processing 5 object(s) completed");
|
||||
assertThat(this.commandLine.getErrorOutput()).contains("Processing 6 object(s) completed");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ package de.kosit.validationtool.cmd;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -34,6 +33,7 @@ import org.junit.Test;
|
|||
|
||||
import de.kosit.validationtool.api.InputFactory;
|
||||
import de.kosit.validationtool.impl.Helper;
|
||||
import de.kosit.validationtool.impl.Helper.Simple;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
|
||||
/**
|
||||
|
|
@ -43,7 +43,6 @@ import de.kosit.validationtool.impl.tasks.CheckAction;
|
|||
*/
|
||||
public class ExtractHtmlActionTest {
|
||||
|
||||
private static final URL REPORT = SerializeReportActionTest.class.getResource("/examples/results/report.xml");
|
||||
|
||||
private ExtractHtmlContentAction action;
|
||||
|
||||
|
|
@ -51,24 +50,24 @@ public class ExtractHtmlActionTest {
|
|||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
tmpDirectory = Files.createTempDirectory("checktool");
|
||||
action = new ExtractHtmlContentAction(Helper.loadTestRepository(), tmpDirectory);
|
||||
this.tmpDirectory = Files.createTempDirectory("checktool");
|
||||
this.action = new ExtractHtmlContentAction(Helper.loadTestRepository(), this.tmpDirectory);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws IOException {
|
||||
FileUtils.deleteDirectory(tmpDirectory.toFile());
|
||||
FileUtils.deleteDirectory(this.tmpDirectory.toFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimple() throws IOException {
|
||||
CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(REPORT));
|
||||
assertThat(action.isSkipped(b)).isTrue();
|
||||
b.setReport(Helper.load(REPORT));
|
||||
action.check(b);
|
||||
assertThat(action.isSkipped(b)).isFalse();
|
||||
action.check(b);
|
||||
final CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(Simple.SIMPLE_VALID));
|
||||
assertThat(this.action.isSkipped(b)).isTrue();
|
||||
b.setReport(Helper.load(Simple.SIMPLE_VALID.toURL()));
|
||||
this.action.check(b);
|
||||
assertThat(this.action.isSkipped(b)).isFalse();
|
||||
this.action.check(b);
|
||||
assertThat(b.isStopped()).isFalse();
|
||||
assertThat(Files.list(tmpDirectory).collect(Collectors.toList())).hasSize(1);
|
||||
assertThat(Files.list(this.tmpDirectory).collect(Collectors.toList())).hasSize(1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ package de.kosit.validationtool.cmd;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
|
@ -30,6 +29,7 @@ import org.junit.Test;
|
|||
|
||||
import de.kosit.validationtool.api.InputFactory;
|
||||
import de.kosit.validationtool.impl.Helper;
|
||||
import de.kosit.validationtool.impl.Helper.Simple;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
|
||||
/**
|
||||
|
|
@ -37,34 +37,33 @@ import de.kosit.validationtool.impl.tasks.CheckAction;
|
|||
*/
|
||||
public class PrintReportActionTest {
|
||||
|
||||
private static final URL REPORT = SerializeReportActionTest.class.getResource("/examples/results/report.xml");
|
||||
|
||||
private CommandLine commandLine;
|
||||
|
||||
private PrintReportAction action;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
commandLine = new CommandLine();
|
||||
commandLine.activate();
|
||||
action = new PrintReportAction();
|
||||
public void setup() {
|
||||
this.commandLine = new CommandLine();
|
||||
this.commandLine.activate();
|
||||
this.action = new PrintReportAction();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDownd() throws IOException {
|
||||
commandLine.deactivate();
|
||||
public void tearDown() {
|
||||
this.commandLine.deactivate();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleSerialize() {
|
||||
CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(REPORT));
|
||||
b.setReport(Helper.load(REPORT));
|
||||
assertThat(action.isSkipped(b)).isFalse();
|
||||
action.check(b);
|
||||
public void testSimpleSerialize() throws MalformedURLException {
|
||||
final CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(Simple.SIMPLE_VALID));
|
||||
b.setReport(Helper.load(Simple.SIMPLE_VALID.toURL()));
|
||||
assertThat(this.action.isSkipped(b)).isFalse();
|
||||
this.action.check(b);
|
||||
assertThat(b.isStopped()).isFalse();
|
||||
assertThat(commandLine.getOutput()).isNotEmpty();
|
||||
// assertThat(commandLine.getOutput()).contains("<?xml version=\"1.0\" ");
|
||||
// assertThat(commandLine.getErrorOutput()).isEmpty();
|
||||
assertThat(this.commandLine.getOutput()).isNotEmpty();
|
||||
assertThat(this.commandLine.getOutput()).contains("<?xml version=\"1.0\" ");
|
||||
assertThat(this.commandLine.getErrorOutput()).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ package de.kosit.validationtool.cmd;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
|
|
@ -33,6 +33,7 @@ import org.junit.Test;
|
|||
|
||||
import de.kosit.validationtool.api.InputFactory;
|
||||
import de.kosit.validationtool.impl.Helper;
|
||||
import de.kosit.validationtool.impl.Helper.Simple;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
|
||||
/**
|
||||
|
|
@ -40,7 +41,6 @@ import de.kosit.validationtool.impl.tasks.CheckAction;
|
|||
*/
|
||||
public class SerializeReportActionTest {
|
||||
|
||||
private static final URL REPORT = SerializeReportActionTest.class.getResource("/examples/results/report.xml");
|
||||
|
||||
private Path tmpDirectory;
|
||||
|
||||
|
|
@ -48,31 +48,31 @@ public class SerializeReportActionTest {
|
|||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
tmpDirectory = Files.createTempDirectory("checktool");
|
||||
action = new SerializeReportAction(tmpDirectory);
|
||||
this.tmpDirectory = Files.createTempDirectory("checktool");
|
||||
this.action = new SerializeReportAction(this.tmpDirectory);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws IOException {
|
||||
FileUtils.deleteDirectory(tmpDirectory.toFile());
|
||||
FileUtils.deleteDirectory(this.tmpDirectory.toFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleSerialize() {
|
||||
CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(REPORT));
|
||||
assertThat(action.isSkipped(b)).isTrue();
|
||||
b.setReport(Helper.load(REPORT));
|
||||
assertThat(action.isSkipped(b)).isFalse();
|
||||
action.check(b);
|
||||
public void testSimpleSerialize() throws MalformedURLException {
|
||||
final CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(Simple.SIMPLE_VALID));
|
||||
assertThat(this.action.isSkipped(b)).isTrue();
|
||||
b.setReport(Helper.load(Simple.SIMPLE_VALID.toURL()));
|
||||
assertThat(this.action.isSkipped(b)).isFalse();
|
||||
this.action.check(b);
|
||||
assertThat(b.isStopped()).isFalse();
|
||||
assertThat(tmpDirectory.toFile().listFiles()).hasSize(1);
|
||||
assertThat(this.tmpDirectory.toFile().listFiles()).hasSize(1);
|
||||
}
|
||||
|
||||
//ERPT-83
|
||||
@Test
|
||||
public void testName(){
|
||||
final String name = "some.name.with.dots";
|
||||
CheckAction.Bag b = new CheckAction.Bag(InputFactory.read("ega".getBytes(), name + ".xml"));
|
||||
final CheckAction.Bag b = new CheckAction.Bag(InputFactory.read("ega".getBytes(), name + ".xml"));
|
||||
assertThat(b.getName()).isEqualTo(name);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,10 +22,11 @@ package de.kosit.validationtool.impl;
|
|||
import static de.kosit.validationtool.api.InputFactory.read;
|
||||
import static de.kosit.validationtool.impl.Helper.Simple.GARBAGE;
|
||||
import static de.kosit.validationtool.impl.Helper.Simple.NOT_WELLFORMED;
|
||||
import static de.kosit.validationtool.impl.Helper.Simple.REJECTED;
|
||||
import static de.kosit.validationtool.impl.Helper.Simple.UNKNOWN;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
|
@ -54,7 +55,7 @@ public class DefaultCheckTest {
|
|||
private DefaultCheck implementation;
|
||||
|
||||
@Before
|
||||
public void setup() throws URISyntaxException {
|
||||
public void setup() {
|
||||
final CheckConfiguration d = new CheckConfiguration(Simple.SCENARIOS);
|
||||
d.setScenarioRepository(new File(Simple.REPOSITORY).toURI());
|
||||
this.implementation = new DefaultCheck(d);
|
||||
|
|
@ -74,8 +75,8 @@ public class DefaultCheckTest {
|
|||
final Result doc = this.implementation.checkInput(read(Simple.FOO));
|
||||
assertThat(doc).isNotNull();
|
||||
assertThat(doc.getReport()).isNotNull();
|
||||
assertThat(doc.isAcceptable()).isFalse();
|
||||
assertThat(doc.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.UNDEFINED);
|
||||
assertThat(doc.isAcceptable()).isTrue();
|
||||
assertThat(doc.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.ACCEPTABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -120,6 +121,17 @@ public class DefaultCheckTest {
|
|||
assertThat(result.isProcessingSuccessful()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoScenario() {
|
||||
final Result result = this.implementation.checkInput(read(UNKNOWN));
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.isWellformed()).isTrue();
|
||||
assertThat(result.isProcessingSuccessful()).isTrue();
|
||||
assertThat(result.isSchemaValid()).isFalse();
|
||||
assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
assertThat(result.isAcceptable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotWellFormed() {
|
||||
final Result result = this.implementation.checkInput(read(NOT_WELLFORMED));
|
||||
|
|
@ -130,7 +142,19 @@ public class DefaultCheckTest {
|
|||
assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
assertThat(result.getReport()).isNotNull();
|
||||
assertThat(result.getReportDocument()).isNotNull();
|
||||
System.out.println(Helper.serialize(result.getReportDocument()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRejectAcceptMatch() {
|
||||
final Result result = this.implementation.checkInput(read(REJECTED));
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.isWellformed()).isTrue();
|
||||
assertThat(result.isSchemaValid()).isTrue();
|
||||
assertThat(result.isProcessingSuccessful()).isTrue();
|
||||
assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
assertThat(result.isAcceptable()).isFalse();
|
||||
assertThat(result.getReport()).isNotNull();
|
||||
assertThat(result.getReportDocument()).isNotNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ public class Helper {
|
|||
|
||||
public static final URI FOO = Simple.ROOT.resolve("input/foo.xml");
|
||||
|
||||
public static final URI REJECTED = Simple.ROOT.resolve("input/withManualReject.xml");
|
||||
|
||||
public static final URI SCENARIOS = ROOT.resolve("scenarios.xml");
|
||||
|
||||
public static final URI REPOSITORY = ROOT.resolve("repository/");
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package de.kosit.validationtool.impl;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
|
@ -19,12 +18,12 @@ import de.kosit.validationtool.impl.Helper.Simple;
|
|||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
public class SimpleScenarioCheck {
|
||||
public class SimpleScenarioCheckTest {
|
||||
|
||||
private DefaultCheck implementation;
|
||||
|
||||
@Before
|
||||
public void setup() throws URISyntaxException {
|
||||
public void setup() {
|
||||
final CheckConfiguration d = new CheckConfiguration(Simple.SCENARIOS);
|
||||
d.setScenarioRepository(Simple.REPOSITORY);
|
||||
this.implementation = new DefaultCheck(d);
|
||||
|
|
@ -49,14 +48,17 @@ public class SimpleScenarioCheck {
|
|||
public void testUnknown() throws MalformedURLException {
|
||||
final Result result = this.implementation.checkInput(InputFactory.read(Simple.UNKNOWN.toURL()));
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.isProcessingSuccessful()).isFalse();
|
||||
assertThat(result.isProcessingSuccessful()).isTrue();
|
||||
assertThat(result.isAcceptable()).isFalse();
|
||||
assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithoutAcceptMatch() throws MalformedURLException {
|
||||
final Result result = this.implementation.checkInput(InputFactory.read(Simple.FOO.toURL()));
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.UNDEFINED);
|
||||
assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.ACCEPTABLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
package de.kosit.validationtool.impl.tasks;
|
||||
|
||||
import static de.kosit.validationtool.impl.tasks.TestBagBuilder.createBag;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import de.kosit.validationtool.api.AcceptRecommendation;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction.Bag;
|
||||
|
||||
/**
|
||||
* Tests the 'acceptMatch' functionality.
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
public class ComputeAcceptanceActionTest {
|
||||
|
||||
private final ComputeAcceptanceAction action = new ComputeAcceptanceAction();
|
||||
|
||||
@Test
|
||||
public void simpleTest() {
|
||||
final Bag bag = createBag(true, true);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.UNDEFINED);
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.ACCEPTABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSchemaFailed() {
|
||||
final Bag bag = createBag(false, true);
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSchematronFailed() {
|
||||
final Bag bag = createBag(true, false);
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidAcceptMatch() {
|
||||
final Bag bag = createBag(true, true);
|
||||
bag.getScenarioSelectionResult().getObject().setAcceptMatch("count(//doesnotExist) = 0");
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.ACCEPTABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptMatchNotSatisfied() {
|
||||
final Bag bag = createBag(true, true);
|
||||
bag.getScenarioSelectionResult().getObject().setAcceptMatch("count(//doesnotExist) = 1");
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptMatchOverridesSchematronErrors() {
|
||||
final Bag bag = createBag(true, false);
|
||||
bag.getScenarioSelectionResult().getObject().setAcceptMatch("count(//doesnotExist) = 0");
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.ACCEPTABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidAcceptMatchOnSchemaFailed() {
|
||||
final Bag bag = createBag(false, true);
|
||||
bag.getScenarioSelectionResult().getObject().setAcceptMatch("count(//doesnotExist) = 0");
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingSchemaCheck() {
|
||||
final Bag bag = createBag(null, Collections.emptyList());
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSchematronCheck() {
|
||||
final Bag bag = createBag(true, true);
|
||||
// remove schematron results
|
||||
bag.getReportInput().getValidationResultsSchematron().clear();
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.ACCEPTABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingReport() {
|
||||
final Bag bag = createBag(false, true);
|
||||
bag.setReport(null);
|
||||
this.action.check(bag);
|
||||
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,8 +1,15 @@
|
|||
package de.kosit.validationtool.impl.tasks;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.oclc.purl.dsdl.svrl.FailedAssert;
|
||||
import org.oclc.purl.dsdl.svrl.SchematronOutput;
|
||||
|
||||
import de.kosit.validationtool.api.Input;
|
||||
import de.kosit.validationtool.api.InputFactory;
|
||||
import de.kosit.validationtool.impl.ContentRepository;
|
||||
import de.kosit.validationtool.impl.Helper;
|
||||
import de.kosit.validationtool.impl.Helper.Simple;
|
||||
|
|
@ -10,10 +17,15 @@ import de.kosit.validationtool.impl.ObjectFactory;
|
|||
import de.kosit.validationtool.impl.model.Result;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction.Bag;
|
||||
import de.kosit.validationtool.model.reportInput.CreateReportInput;
|
||||
import de.kosit.validationtool.model.reportInput.ValidationResultsSchematron;
|
||||
import de.kosit.validationtool.model.reportInput.ValidationResultsSchematron.Results;
|
||||
import de.kosit.validationtool.model.reportInput.XMLSyntaxError;
|
||||
import de.kosit.validationtool.model.scenarios.ResourceType;
|
||||
import de.kosit.validationtool.model.scenarios.ScenarioType;
|
||||
import de.kosit.validationtool.model.scenarios.ValidateWithXmlSchema;
|
||||
|
||||
import net.sf.saxon.s9api.XdmNode;
|
||||
|
||||
/**
|
||||
* Utilities for creating test objects.
|
||||
*
|
||||
|
|
@ -26,7 +38,11 @@ public class TestBagBuilder {
|
|||
}
|
||||
|
||||
public static Bag createBag(final Input input, final boolean parse) {
|
||||
final Bag bag = new Bag(input, new CreateReportInput());
|
||||
return createBag(input, parse, new CreateReportInput());
|
||||
}
|
||||
|
||||
public static Bag createBag(final Input input, final boolean parse, final CreateReportInput reportInput) {
|
||||
final Bag bag = new Bag(input, reportInput);
|
||||
if (parse) {
|
||||
bag.setParserResult(DocumentParseAction.parseDocument(bag.getInput()));
|
||||
}
|
||||
|
|
@ -46,4 +62,36 @@ public class TestBagBuilder {
|
|||
t.initialize(repository, true);
|
||||
return t;
|
||||
}
|
||||
|
||||
private static XdmNode createReport() {
|
||||
return DocumentParseAction.parseDocument(InputFactory.read("<some>xml</some>".getBytes(), "someXml")).getObject();
|
||||
}
|
||||
|
||||
static Bag createBag(final boolean schemaValid, final boolean schematronValid) {
|
||||
final Result<Boolean, XMLSyntaxError> schemaResult = schemaValid ? new Result<>(true)
|
||||
: new Result<>(Collections.singletonList(new XMLSyntaxError()));
|
||||
final List<ValidationResultsSchematron> schematronResult = schematronValid ? Collections.emptyList() : createSchematronError();
|
||||
return createBag(schemaResult, schematronResult);
|
||||
}
|
||||
|
||||
private static List<ValidationResultsSchematron> createSchematronError() {
|
||||
final ValidationResultsSchematron v = new ValidationResultsSchematron();
|
||||
final SchematronOutput out = new SchematronOutput();
|
||||
final FailedAssert f = new FailedAssert();
|
||||
out.getActivePatternAndFiredRuleAndFailedAssert().add(f);
|
||||
final Results r = new Results();
|
||||
r.setSchematronOutput(out);
|
||||
v.setResults(r);
|
||||
return Collections.singletonList(v);
|
||||
}
|
||||
|
||||
static Bag createBag(final Result<Boolean, XMLSyntaxError> schemaResult,
|
||||
final Collection<ValidationResultsSchematron> schematronResult) {
|
||||
final CreateReportInput reportInput = new CreateReportInput();
|
||||
reportInput.getValidationResultsSchematron().addAll(schematronResult);
|
||||
final Bag b = createBag(InputFactory.read("<someXml></someXml>".getBytes(), "someCheck"), true, reportInput);
|
||||
b.setSchemaValidationResult(schemaResult);
|
||||
b.setReport(createReport());
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,330 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to the Koordinierungsstelle für IT-Standards (KoSIT) under
|
||||
~ one or more contributor license agreements. See the NOTICE file
|
||||
~ distributed with this work for additional information
|
||||
~ regarding copyright ownership. KoSIT licenses this file
|
||||
~ to you under the Apache License, Version 2.0 (the
|
||||
~ "License"); you may not use this file except in compliance
|
||||
~ with the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing,
|
||||
~ software distributed under the License is distributed on an
|
||||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
|
||||
<rep:report xmlns:rep="http://www.xoev.de/de/validator/varl/1 " valid="false" varlVersion="1.0.0">
|
||||
<rep:engine>
|
||||
<rep:name>KoSIT POC</rep:name>
|
||||
</rep:engine>
|
||||
<rep:timestamp>2017-09-01T13:13:59.055+02:00</rep:timestamp>
|
||||
<rep:documentIdentification>
|
||||
<rep:documentHash>
|
||||
<rep:hashAlgorithm>SHA-256</rep:hashAlgorithm>
|
||||
<rep:hashValue>4exhW9EJxAbhlZLHZ3mYZ3/hWGG5e6mIpiTAlGTpQ7s=</rep:hashValue>
|
||||
</rep:documentHash>
|
||||
<rep:documentReference>
|
||||
/C:/Developer/source/init/eRechnung-Check/src/test/resources/examples/UBLReady/UBLReady_EU_UBL-NL_20170102_FULL.xml
|
||||
</rep:documentReference>
|
||||
</rep:documentIdentification>
|
||||
<ns2:scenario xmlns:ns2="http://www.xoev.de/de/validator/framework/1/scenarios"
|
||||
xmlns="http://www.xoev.de/de/validator/framework/1/createreportinput">
|
||||
<ns2:name>UBL 2.1 Invoice</ns2:name>
|
||||
<ns2:namespace prefix="invoice">urn:oasis:names:specification:ubl:schema:xsd:Invoice-2</ns2:namespace>
|
||||
<ns2:match>/invoice:Invoice</ns2:match>
|
||||
<ns2:validateWithXmlSchema>
|
||||
<ns2:resource>
|
||||
<ns2:name>UBL 2.1 Invoice</ns2:name>
|
||||
<ns2:location>resources/eRechnung/UBL-2.1/xsdrt/maindoc/UBL-Invoice-2.1.xsd</ns2:location>
|
||||
</ns2:resource>
|
||||
</ns2:validateWithXmlSchema>
|
||||
<ns2:validateWithSchematron>
|
||||
<ns2:resource>
|
||||
<ns2:name>BII Rules for Invoice</ns2:name>
|
||||
<ns2:location>resources/eRechnung/UBL-2.1/xsl/BIIRULES-UBL-T10.xsl</ns2:location>
|
||||
</ns2:resource>
|
||||
</ns2:validateWithSchematron>
|
||||
<ns2:validateWithSchematron>
|
||||
<ns2:resource>
|
||||
<ns2:name>openPEPPOL Rules for Invoice</ns2:name>
|
||||
<ns2:location>resources/eRechnung/UBL-2.1/xsl/OPENPEPPOL-UBL-T10.xsl</ns2:location>
|
||||
</ns2:resource>
|
||||
</ns2:validateWithSchematron>
|
||||
<ns2:createReport>
|
||||
<ns2:resource>
|
||||
<ns2:name>Report für eRechnung</ns2:name>
|
||||
<ns2:location>resources/eRechnung/report.xsl</ns2:location>
|
||||
</ns2:resource>
|
||||
</ns2:createReport>
|
||||
</ns2:scenario>
|
||||
<rep:validationResult>
|
||||
<rep:validationStepResult id="step_1" valid="true">
|
||||
<ns2:resource xmlns:ns2="http://www.xoev.de/de/validator/framework/1/scenarios"
|
||||
xmlns="http://www.xoev.de/de/validator/framework/1/createreportinput">
|
||||
<ns2:name>UBL 2.1 Invoice</ns2:name>
|
||||
<ns2:location>resources/eRechnung/UBL-2.1/xsdrt/maindoc/UBL-Invoice-2.1.xsd</ns2:location>
|
||||
</ns2:resource>
|
||||
</rep:validationStepResult>
|
||||
<rep:validationStepResult id="step_2" valid="false">
|
||||
<ns2:resource xmlns:ns2="http://www.xoev.de/de/validator/framework/1/scenarios"
|
||||
xmlns="http://www.xoev.de/de/validator/framework/1/createreportinput">
|
||||
<ns2:name>BII Rules for Invoice</ns2:name>
|
||||
<ns2:location>resources/eRechnung/UBL-2.1/xsl/BIIRULES-UBL-T10.xsl</ns2:location>
|
||||
</ns2:resource>
|
||||
<rep:message code="CL-T10-R010" id="message_2.1" level="warning"
|
||||
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AllowanceCharge[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][3]/*:AllowanceChargeReasonCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
|
||||
[CL-T10-R010]-Coded allowance and charge reasons SHOULD belong to the UNCL 4465 code list BII2 subset
|
||||
</rep:message>
|
||||
</rep:validationStepResult>
|
||||
<rep:validationStepResult id="step_3" valid="false">
|
||||
<ns2:resource xmlns:ns2="http://www.xoev.de/de/validator/framework/1/scenarios"
|
||||
xmlns="http://www.xoev.de/de/validator/framework/1/createreportinput">
|
||||
<ns2:name>openPEPPOL Rules for Invoice</ns2:name>
|
||||
<ns2:location>resources/eRechnung/UBL-2.1/xsl/OPENPEPPOL-UBL-T10.xsl</ns2:location>
|
||||
</ns2:resource>
|
||||
<rep:message code="EUGEN-T10-R026" id="message_3.1" level="error"
|
||||
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:DocumentCurrencyCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
|
||||
[EUGEN-T10-R026]-A currency code element MUST have a list identifier attribute 'ISO4217'.
|
||||
</rep:message>
|
||||
<rep:message code="EUGEN-T10-R041" id="message_3.2" level="warning"
|
||||
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AccountingSupplierParty[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]">
|
||||
[EUGEN-T10-R041]-The VAT identifier for the supplier SHOULD be prefixed with country code for companies
|
||||
with VAT registration in EU countries
|
||||
</rep:message>
|
||||
<rep:message code="EUGEN-T10-R054" id="message_3.3" level="warning"
|
||||
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AccountingSupplierParty[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]/*:Party[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]/*:PartyLegalEntity[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]/*:CompanyID[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
|
||||
[EUGEN-T10-R054]-A party legal entity company identifier SHOULD have a scheme identifier attribute.
|
||||
</rep:message>
|
||||
<rep:message code="EUGEN-T10-R029" id="message_3.4" level="error"
|
||||
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AllowanceCharge[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]/*:AllowanceChargeReasonCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
|
||||
[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier attribute 'UNCL4465'.
|
||||
</rep:message>
|
||||
<rep:message code="EUGEN-T10-R029" id="message_3.5" level="error"
|
||||
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AllowanceCharge[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][2]/*:AllowanceChargeReasonCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
|
||||
[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier attribute 'UNCL4465'.
|
||||
</rep:message>
|
||||
<rep:message code="EUGEN-T10-R029" id="message_3.6" level="error"
|
||||
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AllowanceCharge[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][3]/*:AllowanceChargeReasonCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
|
||||
[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier attribute 'UNCL4465'.
|
||||
</rep:message>
|
||||
</rep:validationStepResult>
|
||||
</rep:validationResult>
|
||||
<rep:assessment>
|
||||
<rep:reject>
|
||||
<rep:explanation>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" data-report-type="devreport-reject">
|
||||
<head>
|
||||
<title>Pruefbericht der KoSIT</title>
|
||||
<style>
|
||||
body{
|
||||
font-family: Calibri;
|
||||
width: 230mm;
|
||||
}
|
||||
|
||||
table{
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.tbl-errors{
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.tbl-errors td{
|
||||
border: 1px solid lightgray;
|
||||
padding: 2px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
thead{
|
||||
font-weight: bold;
|
||||
background-color: #f0f0f0;
|
||||
padding-top: 6pt;
|
||||
padding-bottom: 2pt;
|
||||
}
|
||||
|
||||
.tbl-meta td{
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
|
||||
tr{
|
||||
vertical-align: bottom;
|
||||
border-bottom: 1px solid #c0c0c0;
|
||||
}
|
||||
|
||||
tr.error{
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
}
|
||||
|
||||
tr.warning{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
tr.pos{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p.important{
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
background-color: #e0e0e0;
|
||||
padding: 3pt;
|
||||
}
|
||||
|
||||
td.right{
|
||||
text-align: right
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Prüfbericht der KoSIT</h1>
|
||||
<h2>Angaben zum geprüften Dokument</h2>
|
||||
<table class="tbl-meta">
|
||||
<tr>
|
||||
<td colspan="2">Dokument:</td>
|
||||
<td colspan="3">
|
||||
/C:/Developer/source/init/eRechnung-Check/src/test/resources/examples/UBLReady/UBLReady_EU_UBL-NL_20170102_FULL.xml
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">Szenario:</td>
|
||||
<td colspan="3"/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">Zeitpunkt:</td>
|
||||
<td colspan="3">1.9.2017 13:13:59</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">Validierungsschritte:</td>
|
||||
<td>Fehler</td>
|
||||
<td>Warnung</td>
|
||||
<td>Information</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p class="important"><b>Konformitätsprüfung:</b>Das geprüfte Dokument enthält 4 Fehler / 3
|
||||
Warnungen. Es ist <b>nicht konform</b> zu den formalen Vorgaben.
|
||||
</p>
|
||||
<table class="tbl-errors">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Pos</th>
|
||||
<th>Code</th>
|
||||
<th>CustomLevel (Level)</th>
|
||||
<th>Step</th>
|
||||
<th>Text</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="warning">
|
||||
<td>1</td>
|
||||
<td>CL-T10-R010</td>
|
||||
<td>warning</td>
|
||||
<td/>
|
||||
<td>[CL-T10-R010]-Coded allowance and charge reasons SHOULD belong to the UNCL 4465
|
||||
code list BII2 subset
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"/>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr class="error">
|
||||
<td>2</td>
|
||||
<td>EUGEN-T10-R026</td>
|
||||
<td>error</td>
|
||||
<td/>
|
||||
<td>[EUGEN-T10-R026]-A currency code element MUST have a list identifier attribute
|
||||
'ISO4217'.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"/>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr class="warning">
|
||||
<td>3</td>
|
||||
<td>EUGEN-T10-R041</td>
|
||||
<td>warning</td>
|
||||
<td/>
|
||||
<td>[EUGEN-T10-R041]-The VAT identifier for the supplier SHOULD be prefixed with
|
||||
country code for companies with VAT registration in EU countries
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"/>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr class="warning">
|
||||
<td>4</td>
|
||||
<td>EUGEN-T10-R054</td>
|
||||
<td>warning</td>
|
||||
<td/>
|
||||
<td>[EUGEN-T10-R054]-A party legal entity company identifier SHOULD have a scheme
|
||||
identifier attribute.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"/>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr class="error">
|
||||
<td>5</td>
|
||||
<td>EUGEN-T10-R029</td>
|
||||
<td>error</td>
|
||||
<td/>
|
||||
<td>[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier
|
||||
attribute 'UNCL4465'.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"/>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr class="error">
|
||||
<td>6</td>
|
||||
<td>EUGEN-T10-R029</td>
|
||||
<td>error</td>
|
||||
<td/>
|
||||
<td>[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier
|
||||
attribute 'UNCL4465'.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"/>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr class="error">
|
||||
<td>7</td>
|
||||
<td>EUGEN-T10-R029</td>
|
||||
<td>error</td>
|
||||
<td/>
|
||||
<td>[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier
|
||||
attribute 'UNCL4465'.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"/>
|
||||
<td/>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="important"><b>Bewertung:</b>Es wird empfohlen das Dokument zurückzuweisen.
|
||||
</p>
|
||||
<p class="info">Erstellt mit: KoSIT POC für das InstructionSet
|
||||
<em/>
|
||||
vom .
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</rep:explanation>
|
||||
</rep:reject>
|
||||
</rep:assessment>
|
||||
</rep:report>
|
||||
|
|
@ -2,4 +2,7 @@
|
|||
|
||||
<foo xmlns="http://validator.kosit.de/test-sample">
|
||||
<inner>asldkfj</inner>
|
||||
<content>
|
||||
<rejected/>
|
||||
</content>
|
||||
</foo>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<simple xmlns="http://validator.kosit.de/test-sample">
|
||||
<inner>asldkfj</inner>
|
||||
<content>
|
||||
<rejected>directly transferred, so this is part of the report</rejected>
|
||||
</content>
|
||||
</simple>
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
<location>report.xsl</location>
|
||||
</resource>
|
||||
</createReport>
|
||||
<acceptMatch>count(//cri:xmlSyntaxError) = 0</acceptMatch>
|
||||
<acceptMatch>count(//test:rejected) = 0</acceptMatch>
|
||||
</scenario>
|
||||
|
||||
<scenario>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue