diff --git a/src/main/java/de/kosit/validationtool/api/Input.java b/src/main/java/de/kosit/validationtool/api/Input.java
index 12f9fee..8d93c7a 100644
--- a/src/main/java/de/kosit/validationtool/api/Input.java
+++ b/src/main/java/de/kosit/validationtool/api/Input.java
@@ -45,7 +45,7 @@ public interface Input {
/**
* The digest algorithm used for computing the {@link #getHashCode()}
*
- * @return the name of the digest algorith
+ * @return the name of the digest algorithm
*/
String getDigestAlgorithm();
diff --git a/src/main/java/de/kosit/validationtool/api/Result.java b/src/main/java/de/kosit/validationtool/api/Result.java
index 4c04ab4..f3ed697 100644
--- a/src/main/java/de/kosit/validationtool/api/Result.java
+++ b/src/main/java/de/kosit/validationtool/api/Result.java
@@ -22,6 +22,7 @@ import org.oclc.purl.dsdl.svrl.FailedAssert;
import org.oclc.purl.dsdl.svrl.SchematronOutput;
import org.w3c.dom.Document;
+import de.kosit.validationtool.impl.model.CustomFailedAssert;
import net.sf.saxon.s9api.XdmNode;
/**
@@ -69,23 +70,31 @@ public interface Result {
/**
* Schnellzugriff auf die Empfehlung zur Weiterverarbeitung des Dokuments.
*
- * @return true wenn {@link AcceptRecommendation#ACCEPTABLE}
+ * @return true wenn {@link AcceptRecommendation#ACCEPTABLE}
*/
boolean isAcceptable();
/**
* Gibt eine Liste mit gefundenen Schema-Validation-Fehler zurück. Diese Liste ist leer, wenn keine Fehler gefunden
* wurden.
+ *
+ * @return List of schema validation errors.
*/
List getSchemaViolations();
/**
* Liefert die Ergebnisse der Schematron-Prüfungen, in der Reihenfolge der Szenario-Konfiguration.
*
- * @return Liste mit Schematron-Ergebnissen
+ * @return List with Schematron results
*/
List getSchematronResult();
+ /**
+ * @return List of custom failed asserts per Schematron level. Only failed assertions with a custom level are
+ * contained. Never null but maybe empty.
+ */
+ List getCustomFailedAsserts();
+
/**
* Returns {@link org.oclc.purl.dsdl.svrl.FailedAssert FailedAsserts} of a schematron evaluation.
*
@@ -96,14 +105,14 @@ public interface Result {
/**
* Liefert ein true, wenn keine Schema-Violations vorhanden sind.
*
- * @return true wenn Schema-valide
+ * @return true if XML Schema compliant
*/
boolean isSchemaValid();
/**
* Liefert ein true, wenn der Prüfling eine well-formed XML-Datei ist.
*
- * @return true wenn well-formed
+ * @return true if wellformed
*/
boolean isWellformed();
@@ -111,7 +120,7 @@ public interface Result {
* Returns true, if schematron has been checked and the result does not contain any {@link FailedAssert
* FailedAsserts}.
*
- * @return true, if valid
+ * @return true, if valid
*/
boolean isSchematronValid();
}
diff --git a/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java b/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java
index 3f522a6..be10111 100644
--- a/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java
+++ b/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java
@@ -17,11 +17,9 @@
package de.kosit.validationtool.impl;
import java.util.ArrayList;
-import java.util.Collection;
+import java.util.List;
import java.util.StringJoiner;
-import jakarta.xml.bind.ValidationEvent;
-import jakarta.xml.bind.ValidationEventHandler;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
@@ -30,11 +28,11 @@ import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
-import lombok.Getter;
-
import de.kosit.validationtool.model.reportInput.XMLSyntaxError;
import de.kosit.validationtool.model.reportInput.XMLSyntaxErrorSeverity;
-
+import jakarta.xml.bind.ValidationEvent;
+import jakarta.xml.bind.ValidationEventHandler;
+import lombok.Getter;
import net.sf.saxon.s9api.MessageListener2;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.XdmNode;
@@ -51,7 +49,7 @@ public class CollectingErrorEventHandler implements ValidationEventHandler, Erro
private static final int stopProcessCount = DEFAULT_ABORT_COUNT;
- private final Collection errors = new ArrayList<>();
+ private final List errors = new ArrayList<>();
private static XMLSyntaxError createError(final XMLSyntaxErrorSeverity severity, final String message) {
final XMLSyntaxError e = new XMLSyntaxError();
diff --git a/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java b/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java
index 66bff80..2e614ce 100644
--- a/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java
+++ b/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java
@@ -20,19 +20,21 @@ import static de.kosit.validationtool.impl.DateFactory.createTimestamp;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.stream.Collectors;
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
+import org.oclc.purl.dsdl.svrl.FailedAssert;
+import org.oclc.purl.dsdl.svrl.SchematronOutput;
import de.kosit.validationtool.api.Check;
import de.kosit.validationtool.api.Configuration;
import de.kosit.validationtool.api.Input;
import de.kosit.validationtool.api.Result;
import de.kosit.validationtool.api.XmlError;
+import de.kosit.validationtool.impl.model.CustomFailedAssert;
import de.kosit.validationtool.impl.tasks.CheckAction;
import de.kosit.validationtool.impl.tasks.CheckAction.Bag;
import de.kosit.validationtool.impl.tasks.ComputeAcceptanceAction;
@@ -47,7 +49,10 @@ import de.kosit.validationtool.impl.xml.ProcessorProvider;
import de.kosit.validationtool.model.reportInput.CreateReportInput;
import de.kosit.validationtool.model.reportInput.EngineType;
import de.kosit.validationtool.model.reportInput.XMLSyntaxError;
-
+import de.kosit.validationtool.model.scenarios.ErrorLevelType;
+import de.kosit.validationtool.model.scenarios.ScenarioType;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
import net.sf.saxon.s9api.Processor;
/**
@@ -141,10 +146,30 @@ public class DefaultCheck implements Check {
result.setProcessingSuccessful(!t.isStopped() && t.isFinished());
result.setSchematronResult(t.getReportInput().getValidationResultsSchematron().stream().filter(e -> e.getResults() != null)
.map(e -> e.getResults().getSchematronOutput()).collect(Collectors.toList()));
+
+ result.setCustomFailedAsserts(buildCustomFailedAssertsList(t, result.getSchematronResult()));
+
return result;
}
- private static List convertErrors(final Collection errors) {
+ private List buildCustomFailedAssertsList(final Bag t, final List schematronResult) {
+ // Get Map of Assertion ID to custom error levels for the current scenario
+ final Map customLevels = Optional.ofNullable(t.getScenarioSelectionResult())
+ .map(de.kosit.validationtool.impl.model.Result::getObject).map(Scenario::getConfiguration)
+ .map(ScenarioType::getCreateReport)
+ .map(r -> r.getCustomLevel().stream()
+ .flatMap(customLevel -> customLevel.getValue().stream().map(id -> Map.entry(id, customLevel.getLevel())))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)))
+ .orElse(Collections.emptyMap());
+
+ // Now check all failed assertions of all schematron validations if they contain a failed assertion with one of
+ // the changed IDs
+ return schematronResult.stream().flatMap(x -> x.getActivePatternAndFiredRuleAndFailedAssert().stream())
+ .filter(FailedAssert.class::isInstance).map(FailedAssert.class::cast).filter(fa -> customLevels.containsKey(fa.getId()))
+ .map(fa -> new CustomFailedAssert(fa, customLevels.get(fa.getId()))).collect(Collectors.toList());
+ }
+
+ private static List convertErrors(final List errors) {
// noinspection unchecked
return (List) (List>) errors;
}
diff --git a/src/main/java/de/kosit/validationtool/impl/DefaultResult.java b/src/main/java/de/kosit/validationtool/impl/DefaultResult.java
index 9892198..162e3f9 100644
--- a/src/main/java/de/kosit/validationtool/impl/DefaultResult.java
+++ b/src/main/java/de/kosit/validationtool/impl/DefaultResult.java
@@ -25,15 +25,14 @@ import org.oclc.purl.dsdl.svrl.SchematronOutput;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.Setter;
-
import de.kosit.validationtool.api.AcceptRecommendation;
import de.kosit.validationtool.api.Result;
import de.kosit.validationtool.api.XmlError;
+import de.kosit.validationtool.impl.model.CustomFailedAssert;
import de.kosit.validationtool.model.reportInput.CreateReportInput;
-
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
import net.sf.saxon.dom.NodeOverNodeInfo;
import net.sf.saxon.s9api.XdmNode;
@@ -67,6 +66,11 @@ public class DefaultResult implements Result {
@Setter(AccessLevel.PACKAGE)
private List schematronResult;
+ /**
+ * List of custom failed asserts per Schematron level. Only failed assertions with a custom level are contained.
+ */
+ private List customFailedAsserts;
+
@Getter
@Setter
private boolean processingSuccessful;
@@ -149,19 +153,28 @@ public class DefaultResult implements Result {
}
private List filterSchematronResult(final Class type) {
- return getSchematronResult() != null
- ? getSchematronResult().stream().flatMap(e -> e.getActivePatternAndFiredRuleAndFailedAssert().stream())
+ return this.schematronResult != null
+ ? this.schematronResult.stream().flatMap(e -> e.getActivePatternAndFiredRuleAndFailedAssert().stream())
.filter(type::isInstance).map(type::cast).collect(Collectors.toList())
: Collections.emptyList();
}
private boolean isSchematronEvaluated() {
- return getSchematronResult() != null
- && getSchematronResult().stream().noneMatch(e -> e.getActivePatternAndFiredRuleAndFailedAssert().isEmpty());
+ return this.schematronResult != null
+ && this.schematronResult.stream().noneMatch(e -> e.getActivePatternAndFiredRuleAndFailedAssert().isEmpty());
}
@Override
public boolean isSchematronValid() {
return isSchematronEvaluated() && getFailedAsserts().isEmpty();
}
+
+ @Override
+ public List getCustomFailedAsserts() {
+ return this.customFailedAsserts;
+ }
+
+ public void setCustomFailedAsserts(List customFailedAsserts) {
+ this.customFailedAsserts = customFailedAsserts;
+ }
}
diff --git a/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java b/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java
index 6306403..267bc23 100644
--- a/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java
+++ b/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java
@@ -17,7 +17,6 @@
package de.kosit.validationtool.impl;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -81,10 +80,9 @@ public class ScenarioRepository {
if (collect.size() == 1) {
result = new Result<>(collect.get(0));
} else if (collect.isEmpty()) {
- result = new Result<>(getFallbackScenario(),
- Collections.singleton("None of the loaded scenarios matches the specified document"));
+ result = new Result<>(getFallbackScenario(), Arrays.asList("None of the loaded scenarios matches the specified document"));
} else {
- result = new Result<>(getFallbackScenario(), Collections.singleton("More than one scenario matches the specified document"));
+ result = new Result<>(getFallbackScenario(), Arrays.asList("More than one scenario matches the specified document"));
}
return result;
diff --git a/src/main/java/de/kosit/validationtool/impl/model/CustomFailedAssert.java b/src/main/java/de/kosit/validationtool/impl/model/CustomFailedAssert.java
new file mode 100644
index 0000000..e2163cb
--- /dev/null
+++ b/src/main/java/de/kosit/validationtool/impl/model/CustomFailedAssert.java
@@ -0,0 +1,41 @@
+package de.kosit.validationtool.impl.model;
+
+import java.util.Objects;
+
+import org.oclc.purl.dsdl.svrl.FailedAssert;
+
+import de.kosit.validationtool.model.scenarios.ErrorLevelType;
+
+/**
+ * This class contains a single Schematron failed assertion that has a custom error level.
+ *
+ * @since 1.6.0
+ */
+public class CustomFailedAssert {
+
+ private final FailedAssert originalFailedAssert;
+
+ private final ErrorLevelType customLevelFlag;
+
+ /**
+ * Constructor
+ *
+ * @param failedAssert The failed assert from Schematron. May not be null.
+ * @param customLevelFlag The custom error level. May not be null.
+ */
+ public CustomFailedAssert(final FailedAssert failedAssert, final ErrorLevelType customLevelFlag) {
+ Objects.requireNonNull(failedAssert);
+ Objects.requireNonNull(customLevelFlag);
+ this.originalFailedAssert = failedAssert;
+ this.customLevelFlag = customLevelFlag;
+ }
+
+ public FailedAssert getFailedAssert() {
+ return this.originalFailedAssert;
+ }
+
+ public ErrorLevelType getCustomLevelFlag() {
+ return this.customLevelFlag;
+ }
+
+}
diff --git a/src/main/java/de/kosit/validationtool/impl/model/Result.java b/src/main/java/de/kosit/validationtool/impl/model/Result.java
index 5f94261..893f586 100644
--- a/src/main/java/de/kosit/validationtool/impl/model/Result.java
+++ b/src/main/java/de/kosit/validationtool/impl/model/Result.java
@@ -17,8 +17,8 @@
package de.kosit.validationtool.impl.model;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -37,14 +37,14 @@ public class Result {
private T object;
- private Collection errors = new ArrayList<>();
+ private List errors = new ArrayList<>();
/**
* Erzeugt ein neues Ergebnis mit Fehler
*
* @param errors die Fehler
*/
- public Result(Collection errors) {
+ public Result(final List errors) {
this(null, errors);
}
@@ -53,7 +53,7 @@ public class Result {
*
* @param o
*/
- public Result(T o) {
+ public Result(final T o) {
this(o, Collections.emptyList());
}
diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java
index 5d0915f..22f03ca 100644
--- a/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java
+++ b/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java
@@ -21,10 +21,6 @@ import java.util.Collections;
import org.apache.commons.io.FilenameUtils;
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.Setter;
-
import de.kosit.validationtool.api.AcceptRecommendation;
import de.kosit.validationtool.api.Input;
import de.kosit.validationtool.impl.Scenario;
@@ -32,7 +28,9 @@ import de.kosit.validationtool.impl.model.Result;
import de.kosit.validationtool.model.reportInput.CreateReportInput;
import de.kosit.validationtool.model.reportInput.ProcessingError;
import de.kosit.validationtool.model.reportInput.XMLSyntaxError;
-
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
import net.sf.saxon.s9api.XdmNode;
/**
@@ -55,9 +53,9 @@ public interface CheckAction {
private Result scenarioSelectionResult;
@Setter(AccessLevel.NONE)
- private CreateReportInput reportInput;
+ private final CreateReportInput reportInput;
- /** Das finale Ergebnis */
+ /** The final result */
private XdmNode report;
private boolean finished;
@@ -66,7 +64,7 @@ public interface CheckAction {
private AcceptRecommendation acceptStatus = AcceptRecommendation.UNDEFINED;
- /** Das zu prüfende Dokument */
+ /** The document to validate */
private Input input;
private Result parserResult;
@@ -85,7 +83,9 @@ public interface CheckAction {
}
/**
- * Signalisiert einen vorzeitigen Stop der Vearbeitung.
+ * Indicates an early stop in processing.
+ *
+ * @param error Error text
*/
public void stopProcessing(final String error) {
stopProcessing(Collections.singleton(error));
diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java
index 7eeb728..57de17f 100644
--- a/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java
+++ b/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java
@@ -17,19 +17,18 @@
package de.kosit.validationtool.impl.tasks;
import java.io.IOException;
+import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
import de.kosit.validationtool.api.Input;
import de.kosit.validationtool.impl.input.XdmNodeInput;
import de.kosit.validationtool.impl.model.Result;
import de.kosit.validationtool.model.reportInput.ValidationResultsWellformedness;
import de.kosit.validationtool.model.reportInput.XMLSyntaxError;
import de.kosit.validationtool.model.reportInput.XMLSyntaxErrorSeverity;
-
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
@@ -75,7 +74,7 @@ public class DocumentParseAction implements CheckAction {
final XMLSyntaxError error = new XMLSyntaxError();
error.setSeverityCode(XMLSyntaxErrorSeverity.SEVERITY_FATAL_ERROR);
error.setMessage(String.format("IOException while reading resource %s: %s", content.getName(), e.getMessage()));
- result = new Result<>(Collections.singleton(error));
+ result = new Result<>(Arrays.asList(error));
}
return result;
diff --git a/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java b/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java
index f8ce55d..86eb983 100644
--- a/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java
+++ b/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java
@@ -164,7 +164,7 @@ public class CommandlineApplicationTest {
final String[] args = { "-s", Paths.get(Simple.SCENARIOS).toString(), "-o", this.output.toString(), "-r",
Paths.get(Simple.REPOSITORY_URI).toString(), Paths.get(Simple.EXAMPLES).toString() };
CommandLineApplication.mainProgram(args);
- assertThat(CommandLine.getErrorOutput()).contains("Processing 8 object(s) completed");
+ assertThat(CommandLine.getErrorOutput()).contains("Processing 9 object(s) completed");
}
@Test
diff --git a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java
index 5144652..d26b295 100644
--- a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java
+++ b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java
@@ -17,6 +17,7 @@
package de.kosit.validationtool.impl;
import static de.kosit.validationtool.api.InputFactory.read;
+import static de.kosit.validationtool.impl.Helper.Simple.FOO_CUSTOM_LEVEL_ERROR;
import static de.kosit.validationtool.impl.Helper.Simple.FOO_SCHEMATRON_INVALID;
import static de.kosit.validationtool.impl.Helper.Simple.GARBAGE;
import static de.kosit.validationtool.impl.Helper.Simple.NOT_WELLFORMED;
@@ -44,7 +45,8 @@ import de.kosit.validationtool.api.Input;
import de.kosit.validationtool.api.InputFactory;
import de.kosit.validationtool.api.Result;
import de.kosit.validationtool.impl.Helper.Simple;
-
+import de.kosit.validationtool.impl.model.CustomFailedAssert;
+import de.kosit.validationtool.model.scenarios.ErrorLevelType;
import net.sf.saxon.s9api.XdmNode;
/**
@@ -239,6 +241,8 @@ public class DefaultCheckTest {
assertThat(result.isAcceptable()).isFalse();
assertThat(result.getReport()).isNotNull();
assertThat(result.getProcessingErrors()).hasSize(1);
+ assertThat(result.getCustomFailedAsserts()).isNotNull();
+ assertThat(result.getCustomFailedAsserts()).hasSize(0);
}
@Test
@@ -254,4 +258,19 @@ public class DefaultCheckTest {
result = this.validCheck.checkInput(domInput);
assertThat(result.isProcessingSuccessful()).isEqualTo(true);
}
+
+ @Test
+ public void testCustomFailedAssertsWarning() {
+ final Result result = this.errorCheck.checkInput(read(FOO_CUSTOM_LEVEL_ERROR));
+ assertThat(result.isSchematronValid()).isFalse();
+ assertThat(result.getFailedAsserts()).isNotEmpty();
+ assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.ACCEPTABLE);
+
+ assertThat(result.getCustomFailedAsserts()).isNotNull();
+ assertThat(result.getCustomFailedAsserts()).hasSize(1);
+ CustomFailedAssert customFailedAssert = result.getCustomFailedAsserts().get(0);
+ assertThat(result.getFailedAsserts().get(0).getId()).isEqualTo(customFailedAssert.getFailedAssert().getId());
+ assertThat(customFailedAssert.getCustomLevelFlag()).isEqualTo(ErrorLevelType.WARNING);
+ }
+
}
diff --git a/src/test/java/de/kosit/validationtool/impl/Helper.java b/src/test/java/de/kosit/validationtool/impl/Helper.java
index f60c8a1..00da5a3 100644
--- a/src/test/java/de/kosit/validationtool/impl/Helper.java
+++ b/src/test/java/de/kosit/validationtool/impl/Helper.java
@@ -57,6 +57,8 @@ public class Helper {
public static final URI FOO_SCHEMATRON_INVALID = EXAMPLES.resolve("foo-schematron-invalid.xml");
+ public static final URI FOO_CUSTOM_LEVEL_ERROR = EXAMPLES.resolve("foo-custom-level-error.xml");
+
public static final URI REJECTED = ROOT.resolve("input/withManualReject.xml");
public static final URI SCENARIOS = ROOT.resolve("scenarios.xml");
diff --git a/src/test/resources/examples/simple/input/foo-custom-level-error.xml b/src/test/resources/examples/simple/input/foo-custom-level-error.xml
new file mode 100644
index 0000000..c802e08
--- /dev/null
+++ b/src/test/resources/examples/simple/input/foo-custom-level-error.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ asldkfj
+ asldkfj
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/examples/simple/scenarios-with-errors.xml b/src/test/resources/examples/simple/scenarios-with-errors.xml
index 2a4896f..a726508 100644
--- a/src/test/resources/examples/simple/scenarios-with-errors.xml
+++ b/src/test/resources/examples/simple/scenarios-with-errors.xml
@@ -52,6 +52,38 @@
+
+ Simple
+
+ Foo schematron error
+
+ http://www.xoev.de/de/validator/framework/1/createreportinput
+ http://validator.kosit.de/test-sample
+ http://validator.kosit.de/test-report
+ /test:foo
+
+
+
+ Sample Schema
+ simple.xsd
+
+
+
+
+ Sample Schematron
+ simple-schematron-error.xsl
+
+
+
+
+ Report für eRechnung
+ report.xsl
+
+ content-2
+
+ count(//test:rejected) = 0
+
+
default