diff --git a/hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/schema/fhir-invariants.sch b/hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/schema/fhir-invariants.sch
index 2622c675fae..8b6d6ccf4ff 100644
--- a/hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/schema/fhir-invariants.sch
+++ b/hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/schema/fhir-invariants.sch
@@ -4503,7 +4503,7 @@
que-1: Group items must have nested items, display items cannot have nested items
- que-7: enableWhen must contain either a 'answer' or a 'hasAnswer' element
+ que-7: enableWhen must contain either a 'answer' or a 'hasAnswer' element
att-1: It the Attachment has data, it SHALL have a contentType
diff --git a/hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/schema/questionnaire.sch b/hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/schema/questionnaire.sch
index d9dc253c6eb..2b12ce9bc94 100644
--- a/hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/schema/questionnaire.sch
+++ b/hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/schema/questionnaire.sch
@@ -76,7 +76,7 @@
que-1: Group items must have nested items, display items cannot have nested items
- que-7: enableWhen must contain either a 'answer' or a 'hasAnswer' element
+ que-7: enableWhen must contain either a 'answer' or a 'hasAnswer' element
att-1: It the Attachment has data, it SHALL have a contentType
diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/SchematronValidationDstu3QuestionnaireTest.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/SchematronValidationDstu3QuestionnaireTest.java
new file mode 100644
index 00000000000..f8438f4e4bc
--- /dev/null
+++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/SchematronValidationDstu3QuestionnaireTest.java
@@ -0,0 +1,126 @@
+package org.hl7.fhir.dstu3.hapi.validation;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.util.TestUtil;
+import ca.uhn.fhir.validation.FhirValidator;
+import ca.uhn.fhir.validation.ValidationResult;
+import org.hl7.fhir.dstu3.model.Enumerations;
+import org.hl7.fhir.dstu3.model.Questionnaire;
+import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemComponent;
+import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemEnableWhenComponent;
+import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType;
+import org.hl7.fhir.dstu3.model.StringType;
+
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SchematronValidationDstu3QuestionnaireTest {
+ private static final Logger ourLog = LoggerFactory.getLogger(SchematronValidationDstu3QuestionnaireTest.class);
+
+ private static FhirContext ourCtx = FhirContext.forDstu3();
+
+ private static int linkIdCnt = 1;
+
+ @Test
+ public void enableWhenWithAnswer() {
+ Questionnaire resource = new Questionnaire();
+ resource.setStatus(Enumerations.PublicationStatus.ACTIVE);
+
+ QuestionnaireItemComponent child1 = createItem(QuestionnaireItemType.GROUP);
+ resource.addItem(child1);
+
+ QuestionnaireItemEnableWhenComponent enableWhen = new QuestionnaireItemEnableWhenComponent();
+ enableWhen.setQuestion("q1");
+ enableWhen.setAnswer(new StringType("a value"));
+ child1.addEnableWhen(enableWhen);
+
+ QuestionnaireItemComponent child21 = createItem(QuestionnaireItemType.STRING);
+ child1.addItem(child21);
+
+ String inputXml = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resource);
+ ourLog.info(inputXml);
+
+ ValidationResult result = validateSchematron(resource);
+ assertTrue(result.isSuccessful());
+ }
+
+ @Test
+ public void enableWhenWithHasAnswer() {
+ Questionnaire resource = new Questionnaire();
+ resource.setStatus(Enumerations.PublicationStatus.ACTIVE);
+
+ QuestionnaireItemComponent child1 = createItem(QuestionnaireItemType.GROUP);
+ resource.addItem(child1);
+
+ QuestionnaireItemEnableWhenComponent enableWhen = new QuestionnaireItemEnableWhenComponent();
+ enableWhen.setQuestion("q1");
+ enableWhen.setHasAnswer(true);
+ child1.addEnableWhen(enableWhen);
+
+ QuestionnaireItemComponent child21 = createItem(QuestionnaireItemType.STRING);
+ child1.addItem(child21);
+
+ String inputXml = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resource);
+ ourLog.info(inputXml);
+
+ ValidationResult result = validateSchematron(resource);
+ assertTrue(result.isSuccessful());
+ }
+
+ @Test
+ public void enableWhenWithHasAnswerAndAnswer() {
+ Questionnaire resource = new Questionnaire();
+ resource.setStatus(Enumerations.PublicationStatus.ACTIVE);
+
+ QuestionnaireItemComponent child1 = createItem(QuestionnaireItemType.GROUP);
+ resource.addItem(child1);
+
+ QuestionnaireItemEnableWhenComponent enableWhen = new QuestionnaireItemEnableWhenComponent();
+ enableWhen.setQuestion("q1");
+ enableWhen.setAnswer(new StringType("a value"));
+ enableWhen.setHasAnswer(true);
+ child1.addEnableWhen(enableWhen);
+
+ QuestionnaireItemComponent child21 = createItem(QuestionnaireItemType.STRING);
+ child1.addItem(child21);
+
+ String inputXml = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resource);
+ ourLog.info(inputXml);
+
+ ValidationResult result = validateSchematron(resource);
+ assertFalse(result.isSuccessful());
+ assertEquals(1, result.getMessages().size());
+ assertThat(result.getMessages().get(0).getMessage(), containsString("que-7"));
+ }
+
+ private QuestionnaireItemComponent createItem(QuestionnaireItemType type) {
+ QuestionnaireItemComponent item = new QuestionnaireItemComponent();
+ item.setLinkId("id-" + linkIdCnt++);
+ item.setType(type);
+ return item;
+ }
+
+ private ValidationResult validateSchematron(Questionnaire resource) {
+ FhirValidator val = ourCtx.newValidator();
+ val.setValidateAgainstStandardSchema(false);
+ val.setValidateAgainstStandardSchematron(true);
+ ValidationResult result = val.validateWithResult(resource);
+
+ String outcomeXml = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
+ ourLog.info(outcomeXml);
+ return result;
+ }
+
+ @AfterClass
+ public static void afterClassClearContext() {
+ TestUtil.clearAllStaticFieldsForUnitTest();
+ }
+}
diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/SchematronValidationR4QuestionnaireTest.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/SchematronValidationR4QuestionnaireTest.java
new file mode 100644
index 00000000000..dc25b8338cf
--- /dev/null
+++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/SchematronValidationR4QuestionnaireTest.java
@@ -0,0 +1,132 @@
+package org.hl7.fhir.r4.validation;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.util.TestUtil;
+import ca.uhn.fhir.validation.FhirValidator;
+import ca.uhn.fhir.validation.ValidationResult;
+
+import org.hl7.fhir.r4.model.Enumerations;
+import org.hl7.fhir.r4.model.Questionnaire;
+import org.hl7.fhir.r4.model.Questionnaire.QuestionnaireItemComponent;
+import org.hl7.fhir.r4.model.Questionnaire.QuestionnaireItemEnableWhenComponent;
+import org.hl7.fhir.r4.model.Questionnaire.QuestionnaireItemType;
+import org.hl7.fhir.r4.model.StringType;
+
+import org.junit.AfterClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Added for #870 - Can be enabled when the FHIR sources are fixed
+ */
+@Ignore("Requires a valid schematron file, e.g. bei merging pull request #869")
+public class SchematronValidationR4QuestionnaireTest {
+ private static final Logger ourLog = LoggerFactory.getLogger(SchematronValidationR4QuestionnaireTest.class);
+
+ private static FhirContext ourCtx = FhirContext.forR4();
+
+ private static int linkIdCnt = 1;
+
+ @Test
+ public void enableWhenWithAnswer() {
+ Questionnaire resource = new Questionnaire();
+ resource.setStatus(Enumerations.PublicationStatus.ACTIVE);
+
+ QuestionnaireItemComponent child1 = createItem(QuestionnaireItemType.GROUP);
+ resource.addItem(child1);
+
+ QuestionnaireItemEnableWhenComponent enableWhen = new QuestionnaireItemEnableWhenComponent();
+ enableWhen.setQuestion("q1");
+ enableWhen.setAnswer(new StringType("a value"));
+ child1.addEnableWhen(enableWhen);
+
+ QuestionnaireItemComponent child21 = createItem(QuestionnaireItemType.STRING);
+ child1.addItem(child21);
+
+ String inputXml = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resource);
+ ourLog.info(inputXml);
+
+ ValidationResult result = validateSchematron(resource);
+ assertTrue(result.isSuccessful());
+ }
+
+ @Test
+ public void enableWhenWithHasAnswer() {
+ Questionnaire resource = new Questionnaire();
+ resource.setStatus(Enumerations.PublicationStatus.ACTIVE);
+
+ QuestionnaireItemComponent child1 = createItem(QuestionnaireItemType.GROUP);
+ resource.addItem(child1);
+
+ QuestionnaireItemEnableWhenComponent enableWhen = new QuestionnaireItemEnableWhenComponent();
+ enableWhen.setQuestion("q1");
+// enableWhen.setHasAnswer(true);
+ child1.addEnableWhen(enableWhen);
+
+ QuestionnaireItemComponent child21 = createItem(QuestionnaireItemType.STRING);
+ child1.addItem(child21);
+
+ String inputXml = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resource);
+ ourLog.info(inputXml);
+
+ ValidationResult result = validateSchematron(resource);
+ assertTrue(result.isSuccessful());
+ }
+
+ @Test
+ public void enableWhenWithHasAnswerAndAnswer() {
+ Questionnaire resource = new Questionnaire();
+ resource.setStatus(Enumerations.PublicationStatus.ACTIVE);
+
+ QuestionnaireItemComponent child1 = createItem(QuestionnaireItemType.GROUP);
+ resource.addItem(child1);
+
+ QuestionnaireItemEnableWhenComponent enableWhen = new QuestionnaireItemEnableWhenComponent();
+ enableWhen.setQuestion("q1");
+ enableWhen.setAnswer(new StringType("a value"));
+// enableWhen.setHasAnswer(true);
+ child1.addEnableWhen(enableWhen);
+
+ QuestionnaireItemComponent child21 = createItem(QuestionnaireItemType.STRING);
+ child1.addItem(child21);
+
+ String inputXml = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resource);
+ ourLog.info(inputXml);
+
+ ValidationResult result = validateSchematron(resource);
+ assertFalse(result.isSuccessful());
+ assertEquals(1, result.getMessages().size());
+ assertThat(result.getMessages().get(0).getMessage(), containsString("que-7"));
+ }
+
+ private QuestionnaireItemComponent createItem(QuestionnaireItemType type) {
+ QuestionnaireItemComponent item = new QuestionnaireItemComponent();
+ item.setLinkId("id-" + linkIdCnt++);
+ item.setType(type);
+ return item;
+ }
+
+ private ValidationResult validateSchematron(Questionnaire resource) {
+ FhirValidator val = ourCtx.newValidator();
+ val.setValidateAgainstStandardSchema(false);
+ val.setValidateAgainstStandardSchematron(true);
+ ValidationResult result = val.validateWithResult(resource);
+
+ String outcomeXml = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
+ ourLog.info(outcomeXml);
+ return result;
+ }
+
+ @AfterClass
+ public static void afterClassClearContext() {
+ TestUtil.clearAllStaticFieldsForUnitTest();
+ }
+}