tidy up and work on tests.
This commit is contained in:
commit
a67693bc4b
|
@ -21868,7 +21868,7 @@ public class VersionConvertor_30_40 {
|
||||||
public static boolean convertsResource(String rt) {
|
public static boolean convertsResource(String rt) {
|
||||||
return Utilities.existsInList(rt, "Parameters", "ActivityDefinition", "AllergyIntolerance", "Appointment", "AppointmentResponse", "AuditEvent", "Basic", "Binary", "BodyStructure", "Bundle", "CapabilityStatement",
|
return Utilities.existsInList(rt, "Parameters", "ActivityDefinition", "AllergyIntolerance", "Appointment", "AppointmentResponse", "AuditEvent", "Basic", "Binary", "BodyStructure", "Bundle", "CapabilityStatement",
|
||||||
"CareTeam", "ClinicalImpression", "CodeSystem", "Communication", "CompartmentDefinition", "Composition", "ConceptMap", "Condition", "Consent", "DetectedIssue", "DeviceUseStatement", "DiagnosticReport", "DocumentReference",
|
"CareTeam", "ClinicalImpression", "CodeSystem", "Communication", "CompartmentDefinition", "Composition", "ConceptMap", "Condition", "Consent", "DetectedIssue", "DeviceUseStatement", "DiagnosticReport", "DocumentReference",
|
||||||
"Encounter", "Endpoint", "EpisodeOfCare", "FamilyMemberHistory", "Flag", "Goal", "GraphDefinition", "Group", "HealthcareService", "Immunization", "ImplementationGuide", "Library", "Linkage", "ListResource", "Location",
|
"Encounter", "Endpoint", "EpisodeOfCare", "FamilyMemberHistory", "Flag", "Goal", "GraphDefinition", "Group", "HealthcareService", "ImagingStudy", "Immunization", "ImplementationGuide", "Library", "Linkage", "ListResource", "Location",
|
||||||
"Medication", "MedicationAdministration", "MedicationDispense", "MedicationRequest", "MedicationStatement", "MessageDefinition", "MessageHeader", "NamingSystem", "Observation", "OperationDefinition", "OperationOutcome",
|
"Medication", "MedicationAdministration", "MedicationDispense", "MedicationRequest", "MedicationStatement", "MessageDefinition", "MessageHeader", "NamingSystem", "Observation", "OperationDefinition", "OperationOutcome",
|
||||||
"Organization", "Patient", "PaymentNotice", "Person", "PlanDefinition", "Practitioner", "PractitionerRole", "ProcessRequest", "Questionnaire", "QuestionnaireResponse", "RiskAssessment", "Schedule", "SearchParameter",
|
"Organization", "Patient", "PaymentNotice", "Person", "PlanDefinition", "Practitioner", "PractitionerRole", "ProcessRequest", "Questionnaire", "QuestionnaireResponse", "RiskAssessment", "Schedule", "SearchParameter",
|
||||||
"Sequence", "Slot", "Specimen", "StructureDefinition", "StructureMap", "Subscription", "Substance", "SupplyDelivery", "TestReport", "TestScript", "ValueSet");
|
"Sequence", "Slot", "Specimen", "StructureDefinition", "StructureMap", "Subscription", "Substance", "SupplyDelivery", "TestReport", "TestScript", "ValueSet");
|
||||||
|
|
|
@ -11896,6 +11896,327 @@ public class VersionConvertor_30_50 {
|
||||||
return tgt;
|
return tgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String URN_DICOM_UID = "urn:dicom:uid";
|
||||||
|
|
||||||
|
public static org.hl7.fhir.r5.model.ImagingStudy convertImagingStudy(org.hl7.fhir.dstu3.model.ImagingStudy src) throws FHIRException {
|
||||||
|
if (src == null)
|
||||||
|
return null;
|
||||||
|
org.hl7.fhir.r5.model.ImagingStudy tgt = new org.hl7.fhir.r5.model.ImagingStudy();
|
||||||
|
copyDomainResource(src, tgt);
|
||||||
|
|
||||||
|
if (src.hasUid()) {
|
||||||
|
org.hl7.fhir.r5.model.Identifier i = new org.hl7.fhir.r5.model.Identifier();
|
||||||
|
i.setSystem(URN_DICOM_UID);
|
||||||
|
i.setValue(src.getUid());
|
||||||
|
tgt.addIdentifier(i);
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.dstu3.model.Identifier t : src.getIdentifier()) {
|
||||||
|
tgt.addIdentifier(convertIdentifier(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src.hasAccession())
|
||||||
|
tgt.addIdentifier(convertIdentifier(src.getAccession()));
|
||||||
|
|
||||||
|
if (src.hasAvailability()) {
|
||||||
|
org.hl7.fhir.dstu3.model.ImagingStudy.InstanceAvailability availability = src.getAvailability();
|
||||||
|
switch (availability) {
|
||||||
|
case OFFLINE:
|
||||||
|
tgt.setStatus(org.hl7.fhir.r5.model.ImagingStudy.ImagingStudyStatus.REGISTERED);
|
||||||
|
break;
|
||||||
|
case UNAVAILABLE:
|
||||||
|
tgt.setStatus(org.hl7.fhir.r5.model.ImagingStudy.ImagingStudyStatus.CANCELLED);
|
||||||
|
break;
|
||||||
|
case ONLINE:
|
||||||
|
case NEARLINE:
|
||||||
|
tgt.setStatus(org.hl7.fhir.r5.model.ImagingStudy.ImagingStudyStatus.AVAILABLE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tgt.setStatus(org.hl7.fhir.r5.model.ImagingStudy.ImagingStudyStatus.UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (org.hl7.fhir.dstu3.model.Coding t : src.getModalityList()) {
|
||||||
|
tgt.addModality(convertCoding(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src.hasPatient())
|
||||||
|
tgt.setSubject(convertReference(src.getPatient()));
|
||||||
|
if (src.hasContext()) {
|
||||||
|
tgt.setEncounter(convertReference(src.getContext()));
|
||||||
|
}
|
||||||
|
if (src.hasStarted()) {
|
||||||
|
|
||||||
|
tgt.setStartedElement(convertDateTime(src.getStartedElement()));
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.dstu3.model.Reference t : src.getBasedOn()) {
|
||||||
|
tgt.addBasedOn(convertReference(t));
|
||||||
|
}
|
||||||
|
if (src.hasReferrer()) {
|
||||||
|
tgt.setReferrer(convertReference(src.getReferrer()));
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.dstu3.model.Reference t : src.getInterpreter()) {
|
||||||
|
tgt.addInterpreter(convertReference(t));
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.dstu3.model.Reference t : src.getEndpoint()) {
|
||||||
|
tgt.addEndpoint(convertReference(t));
|
||||||
|
}
|
||||||
|
if (src.hasNumberOfSeries()) {
|
||||||
|
tgt.setNumberOfSeries(src.getNumberOfSeries());
|
||||||
|
}
|
||||||
|
if (src.hasNumberOfInstances()) {
|
||||||
|
tgt.setNumberOfInstances(src.getNumberOfInstances());
|
||||||
|
}
|
||||||
|
List<org.hl7.fhir.dstu3.model.Reference> procedureReferences = src.getProcedureReference();
|
||||||
|
if (procedureReferences.size() > 0) {
|
||||||
|
tgt.setProcedureReference(convertReference(procedureReferences.get(0)));
|
||||||
|
|
||||||
|
if (procedureReferences.size() > 1) {
|
||||||
|
// TODO print a warning that only one procedure reference could be converted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.dstu3.model.CodeableConcept t : src.getProcedureCode()) {
|
||||||
|
tgt.addProcedureCode(convertCodeableConcept(t));
|
||||||
|
}
|
||||||
|
if (src.hasReason()) {
|
||||||
|
tgt.addReasonCode(convertCodeableConcept(src.getReason()));
|
||||||
|
}
|
||||||
|
if (src.hasDescription()) {
|
||||||
|
tgt.setDescription(src.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesComponent t : src.getSeries()) {
|
||||||
|
tgt.addSeries(convertImagingStudySeriesComponent(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tgt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static org.hl7.fhir.dstu3.model.ImagingStudy convertImagingStudy(org.hl7.fhir.r5.model.ImagingStudy src) throws FHIRException {
|
||||||
|
if (src == null)
|
||||||
|
return null;
|
||||||
|
org.hl7.fhir.dstu3.model.ImagingStudy tgt = new org.hl7.fhir.dstu3.model.ImagingStudy();
|
||||||
|
copyDomainResource(src, tgt);
|
||||||
|
for (org.hl7.fhir.r5.model.Identifier t : src.getIdentifier()) {
|
||||||
|
|
||||||
|
// assuming that there is only one urn:dicom:uid identifier
|
||||||
|
if (URN_DICOM_UID.equals(t.getSystem())) {
|
||||||
|
tgt.setUid(t.getValue());
|
||||||
|
} else {
|
||||||
|
tgt.addIdentifier(convertIdentifier(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (src.hasStatus()) {
|
||||||
|
org.hl7.fhir.r5.model.ImagingStudy.ImagingStudyStatus s = src.getStatus();
|
||||||
|
switch (s) {
|
||||||
|
case REGISTERED:
|
||||||
|
tgt.setAvailability(org.hl7.fhir.dstu3.model.ImagingStudy.InstanceAvailability.OFFLINE);
|
||||||
|
break;
|
||||||
|
case AVAILABLE:
|
||||||
|
tgt.setAvailability(org.hl7.fhir.dstu3.model.ImagingStudy.InstanceAvailability.ONLINE);
|
||||||
|
break;
|
||||||
|
case CANCELLED:
|
||||||
|
tgt.setAvailability(org.hl7.fhir.dstu3.model.ImagingStudy.InstanceAvailability.UNAVAILABLE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.r5.model.Coding t : src.getModality()) {
|
||||||
|
tgt.addModalityList(convertCoding(t));
|
||||||
|
}
|
||||||
|
if (src.hasSubject()) {
|
||||||
|
tgt.setPatient(convertReference(src.getSubject()));
|
||||||
|
}
|
||||||
|
if (src.hasEncounter()) {
|
||||||
|
tgt.setContext(convertReference(src.getEncounter()));
|
||||||
|
}
|
||||||
|
if (src.hasStarted()) {
|
||||||
|
|
||||||
|
tgt.setStartedElement(convertDateTime(src.getStartedElement()));
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.r5.model.Reference t : src.getBasedOn()) {
|
||||||
|
tgt.addBasedOn(convertReference(t));
|
||||||
|
}
|
||||||
|
if (src.hasReferrer()) {
|
||||||
|
tgt.setReferrer(convertReference(src.getReferrer()));
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.r5.model.Reference t : src.getInterpreter()) {
|
||||||
|
tgt.addInterpreter(convertReference(t));
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.r5.model.Reference t : src.getEndpoint()) {
|
||||||
|
tgt.addEndpoint(convertReference(t));
|
||||||
|
}
|
||||||
|
if (src.hasNumberOfSeries()) {
|
||||||
|
tgt.setNumberOfSeries(src.getNumberOfSeries());
|
||||||
|
}
|
||||||
|
if (src.hasNumberOfInstances()) {
|
||||||
|
tgt.setNumberOfInstances(src.getNumberOfInstances());
|
||||||
|
}
|
||||||
|
if (src.hasProcedureReference()) {
|
||||||
|
tgt.addProcedureReference(convertReference(src.getProcedureReference()));
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.r5.model.CodeableConcept t : src.getProcedureCode()) {
|
||||||
|
tgt.addProcedureCode(convertCodeableConcept(t));
|
||||||
|
}
|
||||||
|
// location was added in R4 and does not exist in DSTU3
|
||||||
|
List<org.hl7.fhir.r5.model.CodeableConcept> reasonCodes = src.getReasonCode();
|
||||||
|
if (reasonCodes.size() > 0) {
|
||||||
|
tgt.setReason(convertCodeableConcept(reasonCodes.get(0)));
|
||||||
|
|
||||||
|
if (reasonCodes.size() > 1) {
|
||||||
|
// TODO print a warning that only one reason could be converted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// reasonReference was added in R4 and does not exist in DSTU3
|
||||||
|
// node was added in R4 and does not exist in DSTU3
|
||||||
|
if (src.hasDescription()) {
|
||||||
|
tgt.setDescription(src.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesComponent t : src.getSeries()) {
|
||||||
|
tgt.addSeries(convertImagingStudySeriesComponent(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tgt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesComponent convertImagingStudySeriesComponent(org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesComponent src) throws FHIRException {
|
||||||
|
if (src == null)
|
||||||
|
return null;
|
||||||
|
org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesComponent tgt = new org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesComponent();
|
||||||
|
copyElement(src, tgt);
|
||||||
|
|
||||||
|
if (src.hasUid()) {
|
||||||
|
tgt.setUid(src.getUid());
|
||||||
|
}
|
||||||
|
if (src.hasNumber()) {
|
||||||
|
tgt.setNumber(src.getNumber());
|
||||||
|
}
|
||||||
|
if (src.hasModality()) {
|
||||||
|
tgt.setModality(convertCoding(src.getModality()));
|
||||||
|
}
|
||||||
|
if (src.hasDescription()) {
|
||||||
|
tgt.setDescription(src.getDescription());
|
||||||
|
}
|
||||||
|
if (src.hasNumberOfInstances()) {
|
||||||
|
tgt.setNumberOfInstances(src.getNumberOfInstances());
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.dstu3.model.Reference t : src.getEndpoint()) {
|
||||||
|
tgt.addEndpoint(convertReference(t));
|
||||||
|
}
|
||||||
|
if (src.hasBodySite()) {
|
||||||
|
tgt.setBodySite(convertCoding(src.getBodySite()));
|
||||||
|
}
|
||||||
|
if (src.hasLaterality()) {
|
||||||
|
tgt.setLaterality(convertCoding(src.getLaterality()));
|
||||||
|
}
|
||||||
|
// the specimen element was added in R4 and does not exist in DSTU3
|
||||||
|
if (src.hasStarted()) {
|
||||||
|
tgt.setStartedElement(convertDateTime(src.getStartedElement()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesInstanceComponent t : src.getInstance()) {
|
||||||
|
tgt.addInstance(convertImagingStudySeriesInstanceComponent(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tgt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesComponent convertImagingStudySeriesComponent(org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesComponent src) throws FHIRException {
|
||||||
|
if (src == null)
|
||||||
|
return null;
|
||||||
|
org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesComponent tgt = new org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesComponent();
|
||||||
|
copyElement(src, tgt);
|
||||||
|
|
||||||
|
if (src.hasUid()) {
|
||||||
|
tgt.setUid(src.getUid());
|
||||||
|
}
|
||||||
|
if (src.hasNumber()) {
|
||||||
|
tgt.setNumber(src.getNumber());
|
||||||
|
}
|
||||||
|
if (src.hasModality()) {
|
||||||
|
tgt.setModality(convertCoding(src.getModality()));
|
||||||
|
}
|
||||||
|
if (src.hasDescription()) {
|
||||||
|
tgt.setDescription(src.getDescription());
|
||||||
|
}
|
||||||
|
if (src.hasNumberOfInstances()) {
|
||||||
|
tgt.setNumberOfInstances(src.getNumberOfInstances());
|
||||||
|
}
|
||||||
|
for (org.hl7.fhir.r5.model.Reference t : src.getEndpoint()) {
|
||||||
|
tgt.addEndpoint(convertReference(t));
|
||||||
|
}
|
||||||
|
if (src.hasBodySite()) {
|
||||||
|
tgt.setBodySite(convertCoding(src.getBodySite()));
|
||||||
|
}
|
||||||
|
if (src.hasLaterality()) {
|
||||||
|
tgt.setLaterality(convertCoding(src.getLaterality()));
|
||||||
|
}
|
||||||
|
if (src.hasStarted()) {
|
||||||
|
|
||||||
|
tgt.setStartedElement(convertDateTime(src.getStartedElement()));
|
||||||
|
}
|
||||||
|
// the specimen element was added in R4 and does not exist in DSTU3
|
||||||
|
|
||||||
|
for (org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesInstanceComponent t : src.getInstance()) {
|
||||||
|
tgt.addInstance(convertImagingStudySeriesInstanceComponent(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tgt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String URN_IETF_RFC_3986 = "urn:ietf:rfc:3986";
|
||||||
|
|
||||||
|
private static org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesInstanceComponent convertImagingStudySeriesInstanceComponent(org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesInstanceComponent src) throws FHIRException {
|
||||||
|
if (src == null)
|
||||||
|
return null;
|
||||||
|
org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesInstanceComponent tgt = new org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesInstanceComponent();
|
||||||
|
copyElement(src, tgt);
|
||||||
|
|
||||||
|
if (src.hasUid()) {
|
||||||
|
tgt.setUid(src.getUid());
|
||||||
|
}
|
||||||
|
if (src.hasSopClass()) {
|
||||||
|
org.hl7.fhir.r5.model.Coding c = new org.hl7.fhir.r5.model.Coding();
|
||||||
|
c.setSystem(URN_IETF_RFC_3986);
|
||||||
|
c.setCode(src.getSopClass());
|
||||||
|
tgt.setSopClass(c);
|
||||||
|
}
|
||||||
|
if (src.hasNumber()) {
|
||||||
|
tgt.setNumber(src.getNumber());
|
||||||
|
}
|
||||||
|
if (src.hasTitle()) {
|
||||||
|
tgt.setTitle(src.getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
return tgt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesInstanceComponent convertImagingStudySeriesInstanceComponent(org.hl7.fhir.r5.model.ImagingStudy.ImagingStudySeriesInstanceComponent src) throws FHIRException {
|
||||||
|
if (src == null)
|
||||||
|
return null;
|
||||||
|
org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesInstanceComponent tgt = new org.hl7.fhir.dstu3.model.ImagingStudy.ImagingStudySeriesInstanceComponent();
|
||||||
|
copyElement(src, tgt);
|
||||||
|
|
||||||
|
if (src.hasUid()) {
|
||||||
|
tgt.setUid(src.getUid());
|
||||||
|
}
|
||||||
|
org.hl7.fhir.r5.model.Coding sop = src.getSopClass();
|
||||||
|
if (URN_IETF_RFC_3986.equals(sop.getSystem())) {
|
||||||
|
tgt.setSopClass(sop.getCode());
|
||||||
|
}
|
||||||
|
if (src.hasNumber()) {
|
||||||
|
tgt.setNumber(src.getNumber());
|
||||||
|
}
|
||||||
|
if (src.hasTitle()) {
|
||||||
|
tgt.setTitle(src.getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
return tgt;
|
||||||
|
}
|
||||||
|
|
||||||
public static org.hl7.fhir.r5.model.Immunization convertImmunization(org.hl7.fhir.dstu3.model.Immunization src) throws FHIRException {
|
public static org.hl7.fhir.r5.model.Immunization convertImmunization(org.hl7.fhir.dstu3.model.Immunization src) throws FHIRException {
|
||||||
if (src == null)
|
if (src == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -21286,6 +21607,8 @@ public class VersionConvertor_30_50 {
|
||||||
return convertGroup((org.hl7.fhir.dstu3.model.Group) src);
|
return convertGroup((org.hl7.fhir.dstu3.model.Group) src);
|
||||||
if (src instanceof org.hl7.fhir.dstu3.model.HealthcareService)
|
if (src instanceof org.hl7.fhir.dstu3.model.HealthcareService)
|
||||||
return convertHealthcareService((org.hl7.fhir.dstu3.model.HealthcareService) src);
|
return convertHealthcareService((org.hl7.fhir.dstu3.model.HealthcareService) src);
|
||||||
|
if (src instanceof org.hl7.fhir.dstu3.model.ImagingStudy)
|
||||||
|
return convertImagingStudy((org.hl7.fhir.dstu3.model.ImagingStudy)src);
|
||||||
if (src instanceof org.hl7.fhir.dstu3.model.Immunization)
|
if (src instanceof org.hl7.fhir.dstu3.model.Immunization)
|
||||||
return convertImmunization((org.hl7.fhir.dstu3.model.Immunization) src);
|
return convertImmunization((org.hl7.fhir.dstu3.model.Immunization) src);
|
||||||
if (src instanceof org.hl7.fhir.dstu3.model.ImplementationGuide)
|
if (src instanceof org.hl7.fhir.dstu3.model.ImplementationGuide)
|
||||||
|
@ -21463,6 +21786,8 @@ public class VersionConvertor_30_50 {
|
||||||
return convertGroup((org.hl7.fhir.r5.model.Group) src);
|
return convertGroup((org.hl7.fhir.r5.model.Group) src);
|
||||||
if (src instanceof org.hl7.fhir.r5.model.HealthcareService)
|
if (src instanceof org.hl7.fhir.r5.model.HealthcareService)
|
||||||
return convertHealthcareService((org.hl7.fhir.r5.model.HealthcareService) src);
|
return convertHealthcareService((org.hl7.fhir.r5.model.HealthcareService) src);
|
||||||
|
if (src instanceof org.hl7.fhir.r5.model.ImagingStudy)
|
||||||
|
return convertImagingStudy((org.hl7.fhir.r5.model.ImagingStudy)src);
|
||||||
if (src instanceof org.hl7.fhir.r5.model.Immunization)
|
if (src instanceof org.hl7.fhir.r5.model.Immunization)
|
||||||
return convertImmunization((org.hl7.fhir.r5.model.Immunization) src);
|
return convertImmunization((org.hl7.fhir.r5.model.Immunization) src);
|
||||||
if (src instanceof org.hl7.fhir.r5.model.ImplementationGuide)
|
if (src instanceof org.hl7.fhir.r5.model.ImplementationGuide)
|
||||||
|
@ -21567,7 +21892,7 @@ public class VersionConvertor_30_50 {
|
||||||
public static boolean convertsResource(String rt) {
|
public static boolean convertsResource(String rt) {
|
||||||
return Utilities.existsInList(rt, "Parameters", "ActivityDefinition", "AllergyIntolerance", "Appointment", "AppointmentResponse", "AuditEvent", "Basic", "Binary", "BodyStructure", "Bundle", "CapabilityStatement",
|
return Utilities.existsInList(rt, "Parameters", "ActivityDefinition", "AllergyIntolerance", "Appointment", "AppointmentResponse", "AuditEvent", "Basic", "Binary", "BodyStructure", "Bundle", "CapabilityStatement",
|
||||||
"CareTeam", "ClinicalImpression", "CodeSystem", "Communication", "CompartmentDefinition", "Composition", "ConceptMap", "Condition", "Consent", "DetectedIssue", "DeviceUseStatement", "DiagnosticReport", "DocumentReference",
|
"CareTeam", "ClinicalImpression", "CodeSystem", "Communication", "CompartmentDefinition", "Composition", "ConceptMap", "Condition", "Consent", "DetectedIssue", "DeviceUseStatement", "DiagnosticReport", "DocumentReference",
|
||||||
"Encounter", "Endpoint", "EpisodeOfCare", "FamilyMemberHistory", "Flag", "Goal", "GraphDefinition", "Group", "HealthcareService", "Immunization", "ImplementationGuide", "Library", "Linkage", "ListResource", "Location",
|
"Encounter", "Endpoint", "EpisodeOfCare", "FamilyMemberHistory", "Flag", "Goal", "GraphDefinition", "Group", "HealthcareService", "ImagingStudy", "Immunization", "ImplementationGuide", "Library", "Linkage", "ListResource", "Location",
|
||||||
"Medication", "MedicationAdministration", "MedicationDispense", "MedicationRequest", "MedicationStatement", "MessageDefinition", "MessageHeader", "NamingSystem", "Observation", "OperationDefinition", "OperationOutcome",
|
"Medication", "MedicationAdministration", "MedicationDispense", "MedicationRequest", "MedicationStatement", "MessageDefinition", "MessageHeader", "NamingSystem", "Observation", "OperationDefinition", "OperationOutcome",
|
||||||
"Organization", "Patient", "PaymentNotice", "Person", "PlanDefinition", "Practitioner", "PractitionerRole", "ProcessRequest", "Questionnaire", "QuestionnaireResponse", "RiskAssessment", "Schedule", "SearchParameter",
|
"Organization", "Patient", "PaymentNotice", "Person", "PlanDefinition", "Practitioner", "PractitionerRole", "ProcessRequest", "Questionnaire", "QuestionnaireResponse", "RiskAssessment", "Schedule", "SearchParameter",
|
||||||
"Sequence", "Slot", "Specimen", "StructureDefinition", "StructureMap", "Subscription", "Substance", "SupplyDelivery", "TestReport", "TestScript", "ValueSet");
|
"Sequence", "Slot", "Specimen", "StructureDefinition", "StructureMap", "Subscription", "Substance", "SupplyDelivery", "TestReport", "TestScript", "ValueSet");
|
||||||
|
|
|
@ -34,11 +34,6 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
|
||||||
import org.hl7.fhir.exceptions.PathEngineException;
|
|
||||||
import org.hl7.fhir.r4.conformance.ProfileUtilities;
|
import org.hl7.fhir.r4.conformance.ProfileUtilities;
|
||||||
import org.hl7.fhir.r4.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
import org.hl7.fhir.r4.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r4.context.IWorkerContext;
|
import org.hl7.fhir.r4.context.IWorkerContext;
|
||||||
|
@ -91,10 +86,10 @@ import org.hl7.fhir.r4.model.StructureMap.StructureMapGroupRuleTargetComponent;
|
||||||
import org.hl7.fhir.r4.model.StructureMap.StructureMapGroupRuleTargetParameterComponent;
|
import org.hl7.fhir.r4.model.StructureMap.StructureMapGroupRuleTargetParameterComponent;
|
||||||
import org.hl7.fhir.r4.model.StructureMap.StructureMapGroupTypeMode;
|
import org.hl7.fhir.r4.model.StructureMap.StructureMapGroupTypeMode;
|
||||||
import org.hl7.fhir.r4.model.StructureMap.StructureMapInputMode;
|
import org.hl7.fhir.r4.model.StructureMap.StructureMapInputMode;
|
||||||
import org.hl7.fhir.r4.model.StructureMap.StructureMapModelMode;
|
|
||||||
import org.hl7.fhir.r4.model.StructureMap.StructureMapSourceListMode;
|
import org.hl7.fhir.r4.model.StructureMap.StructureMapSourceListMode;
|
||||||
import org.hl7.fhir.r4.model.StructureMap.StructureMapStructureComponent;
|
|
||||||
import org.hl7.fhir.r4.model.StructureMap.StructureMapTargetListMode;
|
import org.hl7.fhir.r4.model.StructureMap.StructureMapTargetListMode;
|
||||||
|
import org.hl7.fhir.r4.model.StructureMap.StructureMapModelMode;
|
||||||
|
import org.hl7.fhir.r4.model.StructureMap.StructureMapStructureComponent;
|
||||||
import org.hl7.fhir.r4.model.StructureMap.StructureMapTransform;
|
import org.hl7.fhir.r4.model.StructureMap.StructureMapTransform;
|
||||||
import org.hl7.fhir.r4.model.Type;
|
import org.hl7.fhir.r4.model.Type;
|
||||||
import org.hl7.fhir.r4.model.TypeDetails;
|
import org.hl7.fhir.r4.model.TypeDetails;
|
||||||
|
@ -105,6 +100,11 @@ import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
import org.hl7.fhir.r4.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r4.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
import org.hl7.fhir.r4.utils.FHIRLexer.FHIRLexerException;
|
import org.hl7.fhir.r4.utils.FHIRLexer.FHIRLexerException;
|
||||||
import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.exceptions.PathEngineException;
|
||||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
@ -1170,11 +1170,13 @@ public class StructureMapUtilities {
|
||||||
target.addListMode(StructureMapTargetListMode.SHARE);
|
target.addListMode(StructureMapTargetListMode.SHARE);
|
||||||
lexer.next();
|
lexer.next();
|
||||||
target.setListRuleId(lexer.take());
|
target.setListRuleId(lexer.take());
|
||||||
} else if (lexer.getCurrent().equals("first"))
|
} else {
|
||||||
target.addListMode(StructureMapTargetListMode.FIRST);
|
if (lexer.getCurrent().equals("first"))
|
||||||
else
|
target.addListMode(StructureMapTargetListMode.FIRST);
|
||||||
target.addListMode(StructureMapTargetListMode.LAST);
|
else
|
||||||
lexer.next();
|
target.addListMode(StructureMapTargetListMode.LAST);
|
||||||
|
lexer.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1219,7 +1221,7 @@ public class StructureMapUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VariableMode {
|
public enum VariableMode {
|
||||||
INPUT, OUTPUT
|
INPUT, OUTPUT, SHARED
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Variable {
|
public class Variable {
|
||||||
|
@ -1277,16 +1279,25 @@ public class StructureMapUtilities {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String summary() {
|
public String summary() {
|
||||||
CommaSeparatedStringBuilder s = new CommaSeparatedStringBuilder();
|
CommaSeparatedStringBuilder s = new CommaSeparatedStringBuilder();
|
||||||
CommaSeparatedStringBuilder t = new CommaSeparatedStringBuilder();
|
CommaSeparatedStringBuilder t = new CommaSeparatedStringBuilder();
|
||||||
for (Variable v : list)
|
CommaSeparatedStringBuilder sh = new CommaSeparatedStringBuilder();
|
||||||
if (v.mode == VariableMode.INPUT)
|
for (Variable v : list)
|
||||||
s.append(v.summary());
|
switch(v.mode) {
|
||||||
else
|
case INPUT:
|
||||||
t.append(v.summary());
|
s.append(v.summary());
|
||||||
return "source variables ["+s.toString()+"], target variables ["+t.toString()+"]";
|
break;
|
||||||
}
|
case OUTPUT:
|
||||||
|
t.append(v.summary());
|
||||||
|
break;
|
||||||
|
case SHARED:
|
||||||
|
sh.append(v.summary());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "source variables ["+s.toString()+"], target variables ["+t.toString()+"], shared variables ["+sh.toString()+"]";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TransformContext {
|
public class TransformContext {
|
||||||
|
@ -1379,7 +1390,7 @@ public class StructureMapUtilities {
|
||||||
if (source != null) {
|
if (source != null) {
|
||||||
for (Variables v : source) {
|
for (Variables v : source) {
|
||||||
for (StructureMapGroupRuleTargetComponent t : rule.getTarget()) {
|
for (StructureMapGroupRuleTargetComponent t : rule.getTarget()) {
|
||||||
processTarget(rule.getName(), context, v, map, group, t, rule.getSource().size() == 1 ? rule.getSourceFirstRep().getVariable() : null, atRoot);
|
processTarget(rule.getName(), context, v, map, group, t, rule.getSource().size() == 1 ? rule.getSourceFirstRep().getVariable() : null, atRoot, vars);
|
||||||
}
|
}
|
||||||
if (rule.hasRule()) {
|
if (rule.hasRule()) {
|
||||||
for (StructureMapGroupRuleComponent childrule : rule.getRule()) {
|
for (StructureMapGroupRuleComponent childrule : rule.getRule()) {
|
||||||
|
@ -1781,7 +1792,7 @@ public class StructureMapUtilities {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processTarget(String ruleId, TransformContext context, Variables vars, StructureMap map, StructureMapGroupComponent group, StructureMapGroupRuleTargetComponent tgt, String srcVar, boolean atRoot) throws FHIRException {
|
private void processTarget(String ruleId, TransformContext context, Variables vars, StructureMap map, StructureMapGroupComponent group, StructureMapGroupRuleTargetComponent tgt, String srcVar, boolean atRoot, Variables sharedVars) throws FHIRException {
|
||||||
Base dest = null;
|
Base dest = null;
|
||||||
if (tgt.hasContext()) {
|
if (tgt.hasContext()) {
|
||||||
dest = vars.get(VariableMode.OUTPUT, tgt.getContext());
|
dest = vars.get(VariableMode.OUTPUT, tgt.getContext());
|
||||||
|
@ -1795,8 +1806,17 @@ public class StructureMapUtilities {
|
||||||
v = runTransform(ruleId, context, map, group, tgt, vars, dest, tgt.getElement(), srcVar, atRoot);
|
v = runTransform(ruleId, context, map, group, tgt, vars, dest, tgt.getElement(), srcVar, atRoot);
|
||||||
if (v != null && dest != null)
|
if (v != null && dest != null)
|
||||||
v = dest.setProperty(tgt.getElement().hashCode(), tgt.getElement(), v); // reset v because some implementations may have to rewrite v when setting the value
|
v = dest.setProperty(tgt.getElement().hashCode(), tgt.getElement(), v); // reset v because some implementations may have to rewrite v when setting the value
|
||||||
} else if (dest != null)
|
} else if (dest != null) {
|
||||||
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
if (tgt.hasListMode(StructureMapTargetListMode.SHARE)) {
|
||||||
|
v = sharedVars.get(VariableMode.SHARED, tgt.getListRuleId());
|
||||||
|
if (v == null) {
|
||||||
|
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
||||||
|
sharedVars.add(VariableMode.SHARED, tgt.getListRuleId(), v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (tgt.hasVariable() && v != null)
|
if (tgt.hasVariable() && v != null)
|
||||||
vars.add(VariableMode.OUTPUT, tgt.getVariable(), v);
|
vars.add(VariableMode.OUTPUT, tgt.getVariable(), v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
*.out
|
|
@ -0,0 +1,6 @@
|
||||||
|
<fml-tests>
|
||||||
|
<test name="http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2patassignment" source="qr.json" map="qr2pat-assignment.map" output="qr2pat-assignment-res.json" />
|
||||||
|
<test name="http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2patgender" source="qr.json" map="qr2pat-gender.map" output="qr2pat-gender-res.json" />
|
||||||
|
<test name="http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2pathumannametwice" source="qr.json" map="qr2pat-humannametwice.map" output="qr2pat-humannametwice-res.json" />
|
||||||
|
<test name="http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2pathumannameshared" source="qr.json" map="qr2pat-humannameshared.map" output="qr2pat-humannameshared-res.json" />
|
||||||
|
</fml-tests>
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"resourceType": "QuestionnaireResponse",
|
||||||
|
"status": "in-progress",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"linkId": "patient",
|
||||||
|
"text": "Patient",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"linkId": "patient.lastname",
|
||||||
|
"text": "Name",
|
||||||
|
"answer": [
|
||||||
|
{
|
||||||
|
"valueString": "Brönnimann-Bertholet"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"linkId": "patient.firstname",
|
||||||
|
"text": "Vorname",
|
||||||
|
"answer": [
|
||||||
|
{
|
||||||
|
"valueString": "Elisabeth"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"linkId": "patient.sex",
|
||||||
|
"text": "Geschlecht",
|
||||||
|
"answer": [
|
||||||
|
{
|
||||||
|
"valueString": "female"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "Patient",
|
||||||
|
"gender" : "female"
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
map "http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2patassignment" = "qr2patassignment"
|
||||||
|
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as target
|
||||||
|
|
||||||
|
group QuestionnaireResponse(source src : QuestionnaireResponse, target tgt : Patient) {
|
||||||
|
src -> tgt.gender = 'female' "Simple Assignment";
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "Patient",
|
||||||
|
"gender" : "female"
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
map "http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2patgender" = "qr2patgender"
|
||||||
|
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as target
|
||||||
|
|
||||||
|
group QuestionnaireResponse(source src : QuestionnaireResponse, target tgt : Patient) {
|
||||||
|
src.item as item -> tgt as patient then item(item, patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
group item(source src, target tgt: Patient) {
|
||||||
|
src.item as item where linkId.value in ('patient.sex') -> tgt.gender = (item.answer.valueString);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "Patient",
|
||||||
|
"name" : [{
|
||||||
|
"family" : "Brönnimann-Bertholet",
|
||||||
|
"given" : ["Elisabeth"]
|
||||||
|
}],
|
||||||
|
"gender" : "female"
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
map "http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2pathumannameshared" = "qr2pathumannametwice"
|
||||||
|
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as target
|
||||||
|
|
||||||
|
group entry(source src : QuestionnaireResponse, target tgt : Patient) {
|
||||||
|
src.item as item then item(item, tgt);
|
||||||
|
}
|
||||||
|
|
||||||
|
group item(source src, target tgt) {
|
||||||
|
src.item as item then item(item, tgt);
|
||||||
|
src.item as item where linkId.value = 'patient.lastname' -> tgt.name as name share patientName then humanNameFamily(item, name);
|
||||||
|
src.item as item where linkId.value = 'patient.firstname' -> tgt.name as name share patientName then humanNameGiven(item, name);
|
||||||
|
src.item as item where linkId.value = 'patient.sex' -> tgt.gender = (item.answer.valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
group humanNameFamily(source src, target tgt: HumanName) {
|
||||||
|
src.answer as answer -> tgt.family = (answer.valueString);
|
||||||
|
}
|
||||||
|
group humanNameGiven(source src, target tgt: HumanName) {
|
||||||
|
src.answer as answer -> tgt.given = (answer.valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
group administrativeGender(source src, target tgt: code) {
|
||||||
|
src.answer as answer -> tgt = (answer.valueString);
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "Patient",
|
||||||
|
"name" : [{
|
||||||
|
"family" : "Brönnimann-Bertholet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"given" : ["Elisabeth"]
|
||||||
|
}],
|
||||||
|
"gender" : "female"
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
map "http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2pathumannametwice" = "qr2pathumannametwice"
|
||||||
|
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as target
|
||||||
|
|
||||||
|
group entry(source src : QuestionnaireResponse, target tgt : Patient) {
|
||||||
|
src.item as item then item(item, tgt);
|
||||||
|
}
|
||||||
|
|
||||||
|
group item(source src, target tgt) {
|
||||||
|
src.item as item then item(item, tgt);
|
||||||
|
src.item as item where linkId.value = 'patient.lastname' -> tgt.name as name then humanNameFamily(item, name);
|
||||||
|
src.item as item where linkId.value = 'patient.firstname' -> tgt.name as name then humanNameGiven(item, name);
|
||||||
|
src.item as item where linkId.value = 'patient.sex' -> tgt.gender = (item.answer.valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
group humanNameFamily(source src, target tgt: HumanName) {
|
||||||
|
src.answer as answer -> tgt.family = (answer.valueString);
|
||||||
|
}
|
||||||
|
group humanNameGiven(source src, target tgt: HumanName) {
|
||||||
|
src.answer as answer -> tgt.given = (answer.valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
group administrativeGender(source src, target tgt: code) {
|
||||||
|
src.answer as answer -> tgt = (answer.valueString);
|
||||||
|
}
|
|
@ -18,7 +18,8 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||||
NarrativeGeneratorTests.class,
|
NarrativeGeneratorTests.class,
|
||||||
ShexGeneratorTests.class,
|
ShexGeneratorTests.class,
|
||||||
BaseDateTimeTypeTest.class,
|
BaseDateTimeTypeTest.class,
|
||||||
SnapShotGenerationTests.class})
|
SnapShotGenerationTests.class,
|
||||||
|
FHIRMappingLanguageTests.class})
|
||||||
public class AllTests {
|
public class AllTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
package org.hl7.fhir.r4.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.r4.context.SimpleWorkerContext;
|
||||||
|
import org.hl7.fhir.r4.elementmodel.Manager;
|
||||||
|
import org.hl7.fhir.r4.elementmodel.Manager.FhirFormat;
|
||||||
|
import org.hl7.fhir.r4.formats.IParser.OutputStyle;
|
||||||
|
import org.hl7.fhir.r4.formats.JsonParser;
|
||||||
|
import org.hl7.fhir.r4.model.Base;
|
||||||
|
import org.hl7.fhir.r4.model.Coding;
|
||||||
|
import org.hl7.fhir.r4.model.Resource;
|
||||||
|
import org.hl7.fhir.r4.model.ResourceFactory;
|
||||||
|
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionKind;
|
||||||
|
import org.hl7.fhir.r4.model.StructureMap;
|
||||||
|
import org.hl7.fhir.r4.terminologies.ConceptMapEngine;
|
||||||
|
import org.hl7.fhir.r4.test.utils.TestingUtilities;
|
||||||
|
import org.hl7.fhir.r4.utils.StructureMapUtilities;
|
||||||
|
import org.hl7.fhir.r4.utils.StructureMapUtilities.ITransformerServices;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.cache.PackageCacheManager;
|
||||||
|
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||||
|
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
|
|
||||||
|
public class FHIRMappingLanguageTests implements ITransformerServices {
|
||||||
|
|
||||||
|
private List<Resource> outputs = new ArrayList<Resource>();
|
||||||
|
|
||||||
|
static private SimpleWorkerContext context;
|
||||||
|
static private JsonParser jsonParser;
|
||||||
|
|
||||||
|
@Parameters(name = "{index}: {0}")
|
||||||
|
public static Iterable<Object[]> data()
|
||||||
|
throws FileNotFoundException, IOException, ParserConfigurationException, SAXException {
|
||||||
|
Document tests = XMLUtil.parseFileToDom(TestingUtilities.resourceNameToFile("fml", "manifest.xml"));
|
||||||
|
Element test = XMLUtil.getFirstChild(tests.getDocumentElement());
|
||||||
|
List<Object[]> objects = new ArrayList<Object[]>();
|
||||||
|
while (test != null && test.getNodeName().equals("test")) {
|
||||||
|
objects.add(new Object[] { test.getAttribute("name"), test.getAttribute("source"), test.getAttribute("map"),
|
||||||
|
test.getAttribute("output") });
|
||||||
|
test = XMLUtil.getNextSibling(test);
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private String source;
|
||||||
|
private String output;
|
||||||
|
private String map;
|
||||||
|
|
||||||
|
public FHIRMappingLanguageTests(String name, String source, String map, String output) {
|
||||||
|
this.name = name;
|
||||||
|
this.source = source;
|
||||||
|
this.output = output;
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
static public void setUp() throws Exception {
|
||||||
|
if (context == null) {
|
||||||
|
PackageCacheManager pcm = new PackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
|
context = SimpleWorkerContext.fromPackage(pcm.loadPackage("hl7.fhir.core", "4.0.0"));
|
||||||
|
jsonParser = new JsonParser();
|
||||||
|
jsonParser.setOutputStyle(OutputStyle.PRETTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
|
||||||
|
String fileSource = TestingUtilities.resourceNameToFile("fml", source);
|
||||||
|
String fileMap = TestingUtilities.resourceNameToFile("fml", map);
|
||||||
|
String fileOutput = TestingUtilities.resourceNameToFile("fml", output);
|
||||||
|
String fileOutputRes = TestingUtilities.resourceNameToFile("fml", output)+".out";
|
||||||
|
|
||||||
|
outputs.clear();
|
||||||
|
|
||||||
|
boolean ok = false;
|
||||||
|
String msg = null;
|
||||||
|
Resource resource = null;
|
||||||
|
try {
|
||||||
|
StructureMapUtilities scu = new StructureMapUtilities(context, this);
|
||||||
|
org.hl7.fhir.r4.elementmodel.Element src = Manager.parse(context,
|
||||||
|
new ByteArrayInputStream(TextFile.fileToBytes(fileSource)), FhirFormat.JSON);
|
||||||
|
StructureMap structureMap = scu.parse(TextFile.fileToString(fileMap), name);
|
||||||
|
String typeName = scu.getTargetType(structureMap).getType();
|
||||||
|
resource = ResourceFactory.createResource(typeName);
|
||||||
|
scu.transform(null, src, structureMap, resource);
|
||||||
|
ok = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
ok = false;
|
||||||
|
msg = e.getMessage();
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
||||||
|
jsonParser.compose(boas, resource);
|
||||||
|
log(boas.toString());
|
||||||
|
TextFile.bytesToFile(boas.toByteArray(), fileOutputRes);
|
||||||
|
msg = TestingUtilities.checkJsonIsSame(fileOutputRes,fileOutput);
|
||||||
|
assertTrue(msg, Utilities.noString(msg));
|
||||||
|
} else
|
||||||
|
assertTrue("Error, but proper output was expected (" + msg + ")", output.equals("$error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(String message) {
|
||||||
|
System.out.println(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Base createType(Object appInfo, String name) throws FHIRException {
|
||||||
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, name);
|
||||||
|
if (sd != null && sd.getKind() == StructureDefinitionKind.LOGICAL) {
|
||||||
|
return Manager.build(context, sd);
|
||||||
|
} else {
|
||||||
|
if (name.startsWith("http://hl7.org/fhir/StructureDefinition/"))
|
||||||
|
name = name.substring("http://hl7.org/fhir/StructureDefinition/".length());
|
||||||
|
return ResourceFactory.createResourceOrType(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Base createResource(Object appInfo, Base res, boolean atRootofTransform) {
|
||||||
|
if (atRootofTransform)
|
||||||
|
outputs.add((Resource) res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Coding translate(Object appInfo, Coding source, String conceptMapUrl) throws FHIRException {
|
||||||
|
ConceptMapEngine cme = new ConceptMapEngine(context);
|
||||||
|
return cme.translate(source, conceptMapUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Base resolveReference(Object appContext, String url) throws FHIRException {
|
||||||
|
throw new FHIRException("resolveReference is not supported yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Base> performSearch(Object appContext, String url) throws FHIRException {
|
||||||
|
throw new FHIRException("performSearch is not supported yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1170,11 +1170,13 @@ public class StructureMapUtilities {
|
||||||
target.addListMode(StructureMapTargetListMode.SHARE);
|
target.addListMode(StructureMapTargetListMode.SHARE);
|
||||||
lexer.next();
|
lexer.next();
|
||||||
target.setListRuleId(lexer.take());
|
target.setListRuleId(lexer.take());
|
||||||
} else if (lexer.getCurrent().equals("first"))
|
} else {
|
||||||
target.addListMode(StructureMapTargetListMode.FIRST);
|
if (lexer.getCurrent().equals("first"))
|
||||||
else
|
target.addListMode(StructureMapTargetListMode.FIRST);
|
||||||
target.addListMode(StructureMapTargetListMode.LAST);
|
else
|
||||||
lexer.next();
|
target.addListMode(StructureMapTargetListMode.LAST);
|
||||||
|
lexer.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1219,7 +1221,7 @@ public class StructureMapUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VariableMode {
|
public enum VariableMode {
|
||||||
INPUT, OUTPUT
|
INPUT, OUTPUT, SHARED
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Variable {
|
public class Variable {
|
||||||
|
@ -1277,16 +1279,25 @@ public class StructureMapUtilities {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String summary() {
|
public String summary() {
|
||||||
CommaSeparatedStringBuilder s = new CommaSeparatedStringBuilder();
|
CommaSeparatedStringBuilder s = new CommaSeparatedStringBuilder();
|
||||||
CommaSeparatedStringBuilder t = new CommaSeparatedStringBuilder();
|
CommaSeparatedStringBuilder t = new CommaSeparatedStringBuilder();
|
||||||
for (Variable v : list)
|
CommaSeparatedStringBuilder sh = new CommaSeparatedStringBuilder();
|
||||||
if (v.mode == VariableMode.INPUT)
|
for (Variable v : list)
|
||||||
s.append(v.summary());
|
switch(v.mode) {
|
||||||
else
|
case INPUT:
|
||||||
t.append(v.summary());
|
s.append(v.summary());
|
||||||
return "source variables ["+s.toString()+"], target variables ["+t.toString()+"]";
|
break;
|
||||||
}
|
case OUTPUT:
|
||||||
|
t.append(v.summary());
|
||||||
|
break;
|
||||||
|
case SHARED:
|
||||||
|
sh.append(v.summary());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "source variables ["+s.toString()+"], target variables ["+t.toString()+"], shared variables ["+sh.toString()+"]";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TransformContext {
|
public class TransformContext {
|
||||||
|
@ -1379,7 +1390,7 @@ public class StructureMapUtilities {
|
||||||
if (source != null) {
|
if (source != null) {
|
||||||
for (Variables v : source) {
|
for (Variables v : source) {
|
||||||
for (StructureMapGroupRuleTargetComponent t : rule.getTarget()) {
|
for (StructureMapGroupRuleTargetComponent t : rule.getTarget()) {
|
||||||
processTarget(rule.getName(), context, v, map, group, t, rule.getSource().size() == 1 ? rule.getSourceFirstRep().getVariable() : null, atRoot);
|
processTarget(rule.getName(), context, v, map, group, t, rule.getSource().size() == 1 ? rule.getSourceFirstRep().getVariable() : null, atRoot, vars);
|
||||||
}
|
}
|
||||||
if (rule.hasRule()) {
|
if (rule.hasRule()) {
|
||||||
for (StructureMapGroupRuleComponent childrule : rule.getRule()) {
|
for (StructureMapGroupRuleComponent childrule : rule.getRule()) {
|
||||||
|
@ -1781,7 +1792,7 @@ public class StructureMapUtilities {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processTarget(String ruleId, TransformContext context, Variables vars, StructureMap map, StructureMapGroupComponent group, StructureMapGroupRuleTargetComponent tgt, String srcVar, boolean atRoot) throws FHIRException {
|
private void processTarget(String ruleId, TransformContext context, Variables vars, StructureMap map, StructureMapGroupComponent group, StructureMapGroupRuleTargetComponent tgt, String srcVar, boolean atRoot, Variables sharedVars) throws FHIRException {
|
||||||
Base dest = null;
|
Base dest = null;
|
||||||
if (tgt.hasContext()) {
|
if (tgt.hasContext()) {
|
||||||
dest = vars.get(VariableMode.OUTPUT, tgt.getContext());
|
dest = vars.get(VariableMode.OUTPUT, tgt.getContext());
|
||||||
|
@ -1795,8 +1806,17 @@ public class StructureMapUtilities {
|
||||||
v = runTransform(ruleId, context, map, group, tgt, vars, dest, tgt.getElement(), srcVar, atRoot);
|
v = runTransform(ruleId, context, map, group, tgt, vars, dest, tgt.getElement(), srcVar, atRoot);
|
||||||
if (v != null && dest != null)
|
if (v != null && dest != null)
|
||||||
v = dest.setProperty(tgt.getElement().hashCode(), tgt.getElement(), v); // reset v because some implementations may have to rewrite v when setting the value
|
v = dest.setProperty(tgt.getElement().hashCode(), tgt.getElement(), v); // reset v because some implementations may have to rewrite v when setting the value
|
||||||
} else if (dest != null)
|
} else if (dest != null) {
|
||||||
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
if (tgt.hasListMode(StructureMapTargetListMode.SHARE)) {
|
||||||
|
v = sharedVars.get(VariableMode.SHARED, tgt.getListRuleId());
|
||||||
|
if (v == null) {
|
||||||
|
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
||||||
|
sharedVars.add(VariableMode.SHARED, tgt.getListRuleId(), v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (tgt.hasVariable() && v != null)
|
if (tgt.hasVariable() && v != null)
|
||||||
vars.add(VariableMode.OUTPUT, tgt.getVariable(), v);
|
vars.add(VariableMode.OUTPUT, tgt.getVariable(), v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
*.out
|
|
@ -0,0 +1,6 @@
|
||||||
|
<fml-tests>
|
||||||
|
<test name="http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2patassignment" source="qr.json" map="qr2pat-assignment.map" output="qr2pat-assignment-res.json" />
|
||||||
|
<test name="http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2patgender" source="qr.json" map="qr2pat-gender.map" output="qr2pat-gender-res.json" />
|
||||||
|
<test name="http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2pathumannametwice" source="qr.json" map="qr2pat-humannametwice.map" output="qr2pat-humannametwice-res.json" />
|
||||||
|
<test name="http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2pathumannameshared" source="qr.json" map="qr2pat-humannameshared.map" output="qr2pat-humannameshared-res.json" />
|
||||||
|
</fml-tests>
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"resourceType": "QuestionnaireResponse",
|
||||||
|
"status": "in-progress",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"linkId": "patient",
|
||||||
|
"text": "Patient",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"linkId": "patient.lastname",
|
||||||
|
"text": "Name",
|
||||||
|
"answer": [
|
||||||
|
{
|
||||||
|
"valueString": "Brönnimann-Bertholet"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"linkId": "patient.firstname",
|
||||||
|
"text": "Vorname",
|
||||||
|
"answer": [
|
||||||
|
{
|
||||||
|
"valueString": "Elisabeth"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"linkId": "patient.sex",
|
||||||
|
"text": "Geschlecht",
|
||||||
|
"answer": [
|
||||||
|
{
|
||||||
|
"valueString": "female"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "Patient",
|
||||||
|
"gender" : "female"
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
map "http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2patassignment" = "qr2patassignment"
|
||||||
|
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as target
|
||||||
|
|
||||||
|
group QuestionnaireResponse(source src : QuestionnaireResponse, target tgt : Patient) {
|
||||||
|
src -> tgt.gender = 'female' "Simple Assignment";
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "Patient",
|
||||||
|
"gender" : "female"
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
map "http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2patgender" = "qr2patgender"
|
||||||
|
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as target
|
||||||
|
|
||||||
|
group QuestionnaireResponse(source src : QuestionnaireResponse, target tgt : Patient) {
|
||||||
|
src.item as item -> tgt as patient then item(item, patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
group item(source src, target tgt: Patient) {
|
||||||
|
src.item as item where linkId.value in ('patient.sex') -> tgt.gender = (item.answer.valueString);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "Patient",
|
||||||
|
"name" : [{
|
||||||
|
"family" : "Brönnimann-Bertholet",
|
||||||
|
"given" : ["Elisabeth"]
|
||||||
|
}],
|
||||||
|
"gender" : "female"
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
map "http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2pathumannameshared" = "qr2pathumannametwice"
|
||||||
|
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as target
|
||||||
|
|
||||||
|
group entry(source src : QuestionnaireResponse, target tgt : Patient) {
|
||||||
|
src.item as item then item(item, tgt);
|
||||||
|
}
|
||||||
|
|
||||||
|
group item(source src, target tgt) {
|
||||||
|
src.item as item then item(item, tgt);
|
||||||
|
src.item as item where linkId.value = 'patient.lastname' -> tgt.name as name share patientName then humanNameFamily(item, name);
|
||||||
|
src.item as item where linkId.value = 'patient.firstname' -> tgt.name as name share patientName then humanNameGiven(item, name);
|
||||||
|
src.item as item where linkId.value = 'patient.sex' -> tgt.gender = (item.answer.valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
group humanNameFamily(source src, target tgt: HumanName) {
|
||||||
|
src.answer as answer -> tgt.family = (answer.valueString);
|
||||||
|
}
|
||||||
|
group humanNameGiven(source src, target tgt: HumanName) {
|
||||||
|
src.answer as answer -> tgt.given = (answer.valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
group administrativeGender(source src, target tgt: code) {
|
||||||
|
src.answer as answer -> tgt = (answer.valueString);
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "Patient",
|
||||||
|
"name" : [{
|
||||||
|
"family" : "Brönnimann-Bertholet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"given" : ["Elisabeth"]
|
||||||
|
}],
|
||||||
|
"gender" : "female"
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
map "http://github.com/hapifhir/org.hl7.fhir.core/org.hl7.fhir.r4.tests/qr2pathumannametwice" = "qr2pathumannametwice"
|
||||||
|
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source
|
||||||
|
uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as target
|
||||||
|
|
||||||
|
group entry(source src : QuestionnaireResponse, target tgt : Patient) {
|
||||||
|
src.item as item then item(item, tgt);
|
||||||
|
}
|
||||||
|
|
||||||
|
group item(source src, target tgt) {
|
||||||
|
src.item as item then item(item, tgt);
|
||||||
|
src.item as item where linkId.value = 'patient.lastname' -> tgt.name as name then humanNameFamily(item, name);
|
||||||
|
src.item as item where linkId.value = 'patient.firstname' -> tgt.name as name then humanNameGiven(item, name);
|
||||||
|
src.item as item where linkId.value = 'patient.sex' -> tgt.gender = (item.answer.valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
group humanNameFamily(source src, target tgt: HumanName) {
|
||||||
|
src.answer as answer -> tgt.family = (answer.valueString);
|
||||||
|
}
|
||||||
|
group humanNameGiven(source src, target tgt: HumanName) {
|
||||||
|
src.answer as answer -> tgt.given = (answer.valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
group administrativeGender(source src, target tgt: code) {
|
||||||
|
src.answer as answer -> tgt = (answer.valueString);
|
||||||
|
}
|
|
@ -19,6 +19,6 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||||
ShexGeneratorTests.class,
|
ShexGeneratorTests.class,
|
||||||
BaseDateTimeTypeTest.class,
|
BaseDateTimeTypeTest.class,
|
||||||
SnapShotGenerationTests.class})
|
SnapShotGenerationTests.class})
|
||||||
public class AllTests {
|
public class AllR5Tests {
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
package org.hl7.fhir.r5.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||||
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
|
import org.hl7.fhir.r5.model.Base;
|
||||||
|
import org.hl7.fhir.r5.model.Coding;
|
||||||
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
import org.hl7.fhir.r5.model.ResourceFactory;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||||
|
import org.hl7.fhir.r5.model.StructureMap;
|
||||||
|
import org.hl7.fhir.r5.terminologies.ConceptMapEngine;
|
||||||
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
|
import org.hl7.fhir.r5.utils.StructureMapUtilities;
|
||||||
|
import org.hl7.fhir.r5.utils.StructureMapUtilities.ITransformerServices;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.cache.PackageCacheManager;
|
||||||
|
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||||
|
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
|
|
||||||
|
public class FHIRMappingLanguageTests implements ITransformerServices {
|
||||||
|
|
||||||
|
private List<Resource> outputs = new ArrayList<Resource>();
|
||||||
|
|
||||||
|
static private SimpleWorkerContext context;
|
||||||
|
static private JsonParser jsonParser;
|
||||||
|
|
||||||
|
@Parameters(name = "{index}: {0}")
|
||||||
|
public static Iterable<Object[]> data()
|
||||||
|
throws FileNotFoundException, IOException, ParserConfigurationException, SAXException {
|
||||||
|
Document tests = XMLUtil.parseFileToDom(TestingUtilities.resourceNameToFile("fml", "manifest.xml"));
|
||||||
|
Element test = XMLUtil.getFirstChild(tests.getDocumentElement());
|
||||||
|
List<Object[]> objects = new ArrayList<Object[]>();
|
||||||
|
while (test != null && test.getNodeName().equals("test")) {
|
||||||
|
objects.add(new Object[] { test.getAttribute("name"), test.getAttribute("source"), test.getAttribute("map"),
|
||||||
|
test.getAttribute("output") });
|
||||||
|
test = XMLUtil.getNextSibling(test);
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private String source;
|
||||||
|
private String output;
|
||||||
|
private String map;
|
||||||
|
|
||||||
|
public FHIRMappingLanguageTests(String name, String source, String map, String output) {
|
||||||
|
this.name = name;
|
||||||
|
this.source = source;
|
||||||
|
this.output = output;
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
static public void setUp() throws Exception {
|
||||||
|
if (context == null) {
|
||||||
|
PackageCacheManager pcm = new PackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
|
context = SimpleWorkerContext.fromPackage(pcm.loadPackage("hl7.fhir.core", "4.0.0"));
|
||||||
|
jsonParser = new JsonParser();
|
||||||
|
jsonParser.setOutputStyle(OutputStyle.PRETTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
|
||||||
|
String fileSource = TestingUtilities.resourceNameToFile("fml", source);
|
||||||
|
String fileMap = TestingUtilities.resourceNameToFile("fml", map);
|
||||||
|
String fileOutput = TestingUtilities.resourceNameToFile("fml", output);
|
||||||
|
String fileOutputRes = TestingUtilities.resourceNameToFile("fml", output)+".out";
|
||||||
|
|
||||||
|
outputs.clear();
|
||||||
|
|
||||||
|
boolean ok = false;
|
||||||
|
String msg = null;
|
||||||
|
Resource resource = null;
|
||||||
|
try {
|
||||||
|
StructureMapUtilities scu = new StructureMapUtilities(context, this);
|
||||||
|
org.hl7.fhir.r5.elementmodel.Element src = Manager.parse(context,
|
||||||
|
new ByteArrayInputStream(TextFile.fileToBytes(fileSource)), FhirFormat.JSON);
|
||||||
|
StructureMap structureMap = scu.parse(TextFile.fileToString(fileMap), name);
|
||||||
|
String typeName = scu.getTargetType(structureMap).getType();
|
||||||
|
resource = ResourceFactory.createResource(typeName);
|
||||||
|
scu.transform(null, src, structureMap, resource);
|
||||||
|
ok = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
ok = false;
|
||||||
|
msg = e.getMessage();
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
||||||
|
jsonParser.compose(boas, resource);
|
||||||
|
log(boas.toString());
|
||||||
|
TextFile.bytesToFile(boas.toByteArray(), fileOutputRes);
|
||||||
|
msg = TestingUtilities.checkJsonIsSame(fileOutputRes,fileOutput);
|
||||||
|
assertTrue(msg, Utilities.noString(msg));
|
||||||
|
} else
|
||||||
|
assertTrue("Error, but proper output was expected (" + msg + ")", output.equals("$error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(String message) {
|
||||||
|
System.out.println(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Base createType(Object appInfo, String name) throws FHIRException {
|
||||||
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, name);
|
||||||
|
if (sd != null && sd.getKind() == StructureDefinitionKind.LOGICAL) {
|
||||||
|
return Manager.build(context, sd);
|
||||||
|
} else {
|
||||||
|
if (name.startsWith("http://hl7.org/fhir/StructureDefinition/"))
|
||||||
|
name = name.substring("http://hl7.org/fhir/StructureDefinition/".length());
|
||||||
|
return ResourceFactory.createResourceOrType(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Base createResource(Object appInfo, Base res, boolean atRootofTransform) {
|
||||||
|
if (atRootofTransform)
|
||||||
|
outputs.add((Resource) res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Coding translate(Object appInfo, Coding source, String conceptMapUrl) throws FHIRException {
|
||||||
|
ConceptMapEngine cme = new ConceptMapEngine(context);
|
||||||
|
return cme.translate(source, conceptMapUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Base resolveReference(Object appContext, String url) throws FHIRException {
|
||||||
|
throw new FHIRException("resolveReference is not supported yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Base> performSearch(Object appContext, String url) throws FHIRException {
|
||||||
|
throw new FHIRException("performSearch is not supported yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -57,6 +57,8 @@ public class ProfileUtilitiesTests {
|
||||||
else {
|
else {
|
||||||
b.setBase(null);
|
b.setBase(null);
|
||||||
f.setBase(null);
|
f.setBase(null);
|
||||||
|
b.setRequirements(null);
|
||||||
|
f.setRequirements(null);
|
||||||
ok = Base.compareDeep(b, f, true);
|
ok = Base.compareDeep(b, f, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +100,12 @@ public class ProfileUtilitiesTests {
|
||||||
else {
|
else {
|
||||||
f.setBase(null);
|
f.setBase(null);
|
||||||
b.setBase(null);
|
b.setBase(null);
|
||||||
|
b.setRequirements(null);
|
||||||
|
f.setRequirements(null);
|
||||||
|
b.setComment(null);
|
||||||
|
f.setComment(null);
|
||||||
|
b.setDefinition(null);
|
||||||
|
f.setDefinition(null);
|
||||||
ok = Base.compareDeep(b, f, true);
|
ok = Base.compareDeep(b, f, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,7 @@ import org.hl7.fhir.r5.model.TypeDetails;
|
||||||
import org.hl7.fhir.r5.model.UriType;
|
import org.hl7.fhir.r5.model.UriType;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
|
@ -872,15 +873,55 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkCodeableConcept(List<ValidationMessage> errors, String path, Element focus, CodeableConcept fixed) {
|
|
||||||
|
private boolean hasErrors(List<ValidationMessage> errors) {
|
||||||
|
if (errors!=null) {
|
||||||
|
for (ValidationMessage vm : errors) {
|
||||||
|
if (vm.getLevel() == IssueSeverity.FATAL || vm.getLevel() == IssueSeverity.ERROR) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCodeableConcept(List<ValidationMessage> errors, String path, Element focus, CodeableConcept fixed,
|
||||||
|
boolean pattern) {
|
||||||
checkFixedValue(errors, path + ".text", focus.getNamedChild("text"), fixed.getTextElement(), "text", focus);
|
checkFixedValue(errors, path + ".text", focus.getNamedChild("text"), fixed.getTextElement(), "text", focus);
|
||||||
List<Element> codings = new ArrayList<Element>();
|
List<Element> codings = new ArrayList<Element>();
|
||||||
focus.getNamedChildren("coding", codings);
|
focus.getNamedChildren("coding", codings);
|
||||||
if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, codings.size() == fixed.getCoding().size(),
|
if (pattern) {
|
||||||
"Expected " + Integer.toString(fixed.getCoding().size()) + " but found " + Integer.toString(codings.size()) + " coding elements")) {
|
if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, codings.size() >= fixed.getCoding().size(),
|
||||||
for (int i = 0; i < codings.size(); i++)
|
"Expected " + Integer.toString(fixed.getCoding().size()) + " but found " + Integer.toString(codings.size())
|
||||||
checkFixedValue(errors, path + ".coding", codings.get(i), fixed.getCoding().get(i), "coding", focus);
|
+ " coding elements")) {
|
||||||
|
for (int i = 0; i < fixed.getCoding().size(); i++) {
|
||||||
|
Coding fixedCoding = fixed.getCoding().get(i);
|
||||||
|
boolean found = false;
|
||||||
|
List<ValidationMessage> errorsFixed = null;
|
||||||
|
for (int j = 0; j < codings.size() && !found; ++j) {
|
||||||
|
errorsFixed = new ArrayList<ValidationMessage>();
|
||||||
|
checkFixedValue(errorsFixed, path + ".coding", codings.get(j), fixedCoding, "coding", focus);
|
||||||
|
if (!hasErrors(errorsFixed)) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, false,
|
||||||
|
"Expected patternCodeableConcept not found for"+
|
||||||
|
" system: " + fixedCoding.getSystemElement().asStringValue() +
|
||||||
|
" code: " + fixedCoding.getCodeElement().asStringValue() +
|
||||||
|
" display: " + fixedCoding.getDisplayElement().asStringValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, codings.size() == fixed.getCoding().size(),
|
||||||
|
"Expected " + Integer.toString(fixed.getCoding().size()) + " but found " + Integer.toString(codings.size())
|
||||||
|
+ " coding elements")) {
|
||||||
|
for (int i = 0; i < codings.size(); i++)
|
||||||
|
checkFixedValue(errors, path + ".coding", codings.get(i), fixed.getCoding().get(i), "coding", focus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1292,8 +1333,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
// return b.toString();
|
// return b.toString();
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
|
||||||
private void checkFixedValue(List<ValidationMessage> errors, String path, Element focus, org.hl7.fhir.r5.model.Element fixed, String propName, Element parent) {
|
private void checkFixedValue(List<ValidationMessage> errors, String path, Element focus, org.hl7.fhir.r5.model.Element fixed, String propName, Element parent) {
|
||||||
|
checkFixedValue(errors, path, focus, fixed, propName, parent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkFixedValue(List<ValidationMessage> errors, String path, Element focus, org.hl7.fhir.r5.model.Element fixed, String propName, Element parent, boolean pattern) {
|
||||||
if ((fixed == null || fixed.isEmpty()) && focus == null)
|
if ((fixed == null || fixed.isEmpty()) && focus == null)
|
||||||
; // this is all good
|
; // this is all good
|
||||||
else if (fixed == null && focus != null)
|
else if (fixed == null && focus != null)
|
||||||
|
@ -1356,7 +1401,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
else if (fixed instanceof HumanName)
|
else if (fixed instanceof HumanName)
|
||||||
checkHumanName(errors, path, focus, (HumanName) fixed);
|
checkHumanName(errors, path, focus, (HumanName) fixed);
|
||||||
else if (fixed instanceof CodeableConcept)
|
else if (fixed instanceof CodeableConcept)
|
||||||
checkCodeableConcept(errors, path, focus, (CodeableConcept) fixed);
|
checkCodeableConcept(errors, path, focus, (CodeableConcept) fixed, pattern);
|
||||||
else if (fixed instanceof Timing)
|
else if (fixed instanceof Timing)
|
||||||
checkTiming(errors, path, focus, (Timing) fixed);
|
checkTiming(errors, path, focus, (Timing) fixed);
|
||||||
else if (fixed instanceof Period)
|
else if (fixed instanceof Period)
|
||||||
|
@ -1622,8 +1667,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.hasFixed())
|
if (context.hasFixed()) {
|
||||||
checkFixedValue(errors,path,e, context.getFixed(), context.getSliceName(), null);
|
checkFixedValue(errors,path,e, context.getFixed(), context.getSliceName(), null, false);
|
||||||
|
}
|
||||||
|
if (context.hasPattern()) {
|
||||||
|
checkFixedValue(errors, path, e, context.getPattern(), context.getSliceName(), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
// for nothing to check
|
// for nothing to check
|
||||||
}
|
}
|
||||||
|
@ -3823,6 +3872,9 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
|
||||||
if (ei.definition.hasFixed()) {
|
if (ei.definition.hasFixed()) {
|
||||||
checkFixedValue(errors,ei.path, ei.element, ei.definition.getFixed(), ei.definition.getSliceName(), null);
|
checkFixedValue(errors,ei.path, ei.element, ei.definition.getFixed(), ei.definition.getSliceName(), null);
|
||||||
}
|
}
|
||||||
|
if (ei.definition.hasPattern()) {
|
||||||
|
checkFixedValue(errors,ei.path, ei.element, ei.definition.getPattern(), ei.definition.getSliceName(), null, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (type.equals("Identifier")) {
|
if (type.equals("Identifier")) {
|
||||||
checkIdentifier(errors, ei.path, ei.element, ei.definition);
|
checkIdentifier(errors, ei.path, ei.element, ei.definition);
|
||||||
|
|
|
@ -10,6 +10,6 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||||
ValidationEngineTests.class,
|
ValidationEngineTests.class,
|
||||||
JsonSchemaTests.class,
|
JsonSchemaTests.class,
|
||||||
CDAValidationTestCase.class})
|
CDAValidationTestCase.class})
|
||||||
public class AllTests {
|
public class AllR5ValidationTests {
|
||||||
|
|
||||||
}
|
}
|
|
@ -467,7 +467,40 @@
|
||||||
"source" : "extension-slice-profile.xml",
|
"source" : "extension-slice-profile.xml",
|
||||||
"errorCount": 0
|
"errorCount": 0
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"slice-by-polymorphic-type2.xml" : {
|
||||||
|
"errorCount": 0,
|
||||||
|
"profile" : {
|
||||||
|
"source" : "slice-by-polymorphic-type2-profile.xml",
|
||||||
|
"errorCount": 0
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
"observation-bp-validationfails.xml" : {
|
||||||
|
"errorCount": 4,
|
||||||
|
"errors": [
|
||||||
|
"ERROR: Observation.component[1]: Error in discriminator at Observation.component:SystolicBP.code.coding: slicing found",
|
||||||
|
"ERROR: Observation.component[2]: Error in discriminator at Observation.component:SystolicBP.code.coding: slicing found",
|
||||||
|
"ERROR: Observation.component[1]: Error in discriminator at Observation.component:DiastolicBP.code.coding: slicing found",
|
||||||
|
"ERROR: Observation.component[2]: Error in discriminator at Observation.component:DiastolicBP.code.coding: slicing found"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"observation-bp.xml" : {
|
||||||
|
"errorCount": 0,
|
||||||
|
"profile" : {
|
||||||
|
"source" : "observation-bp-profile.xml",
|
||||||
|
"errorCount": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"observation-bp-bad-onlydiastolic.xml" : {
|
||||||
|
"errorCount": 0,
|
||||||
|
"profile" : {
|
||||||
|
"source" : "observation-bp-profile.xml",
|
||||||
|
"errorCount": 1,
|
||||||
|
"errors": [
|
||||||
|
"ERROR: Observation: Profile http://hl7.org/fhir/StructureDefinition/observation-bp-profile, Element 'Observation.component[SystolicBP]': minimum required = 1, but only found 0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"observation-cholesterol-good.xml" : {
|
"observation-cholesterol-good.xml" : {
|
||||||
"errorCount": 0
|
"errorCount": 0
|
||||||
},
|
},
|
||||||
|
@ -489,7 +522,21 @@
|
||||||
"source" : "invariant.profile.xml",
|
"source" : "invariant.profile.xml",
|
||||||
"errorCount": 1
|
"errorCount": 1
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"observation-triglyceride-good.xml" : {
|
||||||
|
"warningCount": 1,
|
||||||
|
"errorCount": 0,
|
||||||
|
"warnings": ["WARNING: Observation.code.coding[1]: The display \"Triglyceride [Moles/volume] in Serum or Plasma\" is not a valid display for the code {http://loinc.org}35217-9 - should be one of [\"Triglyceride [Mass or Moles/volume] in Serum or Plasma\",\"Trigl SerPl-msCnc\""]
|
||||||
|
},
|
||||||
|
"observation-triglyceride-good2.xml" : {
|
||||||
|
"warningCount": 1,
|
||||||
|
"errorCount": 0,
|
||||||
|
"warnings": ["WARNING: Observation.code.coding[2]: The display \"Triglyceride [Moles/volume] in Serum or Plasma\" is not a valid display for the code {http://loinc.org}35217-9 - should be one of [\"Triglyceride [Mass or Moles/volume] in Serum or Plasma\",\"Trigl SerPl-msCnc\""]
|
||||||
|
},
|
||||||
|
"observation-triglyceride-bad-wrongcode.xml" : {
|
||||||
|
"errorCount": 1,
|
||||||
|
"errors": ["ERROR: Observation.code: Expected patternCodeableConcept not found for system: http://loinc.org code: 35217-9 display: Triglyceride [Moles/volume] in Serum or Plasma"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,250 @@
|
||||||
|
<Observation xmlns="http://hl7.org/fhir">
|
||||||
|
<!-- extract from https://www.hl7.org/fhir/observation-example-bloodpressure.xml,
|
||||||
|
changed id from blood-pressure to observation-bp and removed systolic loinc coide that observation fails -->
|
||||||
|
<id value="observation-bp-bad-onlydiastolic" />
|
||||||
|
<text>
|
||||||
|
<status value="generated" />
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<p>
|
||||||
|
<b>Generated Narrative with Details</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>id</b>
|
||||||
|
: blood-pressure
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>meta</b>
|
||||||
|
:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>identifier</b>
|
||||||
|
: urn:uuid:187e0c12-8dd2-67e2-99b2-bf273c878281
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>basedOn</b>
|
||||||
|
:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>status</b>
|
||||||
|
: final
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>category</b>
|
||||||
|
: Vital Signs
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/observation-category code
|
||||||
|
'vital-signs' = 'Vital Signs', given as 'Vital
|
||||||
|
Signs'})</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>code</b>:
|
||||||
|
Blood pressure systolic & diastolic
|
||||||
|
<span>(Details : {LOINC code '85354-9' = 'Blood pressure
|
||||||
|
panel with all children optional', given as 'Blood pressure
|
||||||
|
panel with all children optional'})</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>subject</b>
|
||||||
|
:
|
||||||
|
<a>Patient/example</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>effective</b>
|
||||||
|
: 17/09/2012
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>performer</b>
|
||||||
|
:
|
||||||
|
<a>Practitioner/example</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>interpretation</b>
|
||||||
|
: Below low normal
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
|
||||||
|
code 'L' = 'Low', given as 'low'})</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>bodySite</b>
|
||||||
|
: Right arm
|
||||||
|
<span>(Details : {SNOMED CT code '368209003' = 'Right
|
||||||
|
upper arm', given as 'Right arm'})</span>
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
<b>component</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>code</b>
|
||||||
|
: Systolic blood pressure
|
||||||
|
<span>(Details : {LOINC code '8480-6' = 'Systolic blood
|
||||||
|
pressure', given as 'Systolic blood pressure'};
|
||||||
|
{SNOMED CT code '271649006' = 'Systolic blood
|
||||||
|
pressure', given as 'Systolic blood pressure'};
|
||||||
|
{http://acme.org/devices/clinical-codes code 'bp-s' =
|
||||||
|
'bp-s', given as 'Systolic Blood pressure'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>value</b>
|
||||||
|
: 107 mmHg
|
||||||
|
<span> (Details: UCUM code mm[Hg] = 'mmHg')</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>interpretation</b>
|
||||||
|
: Normal
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
|
||||||
|
code 'N' = 'Normal', given as 'normal'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
<b>component</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>code</b>
|
||||||
|
: Diastolic blood pressure
|
||||||
|
<span>(Details : {LOINC code '8462-4' = 'Diastolic
|
||||||
|
blood pressure', given as 'Diastolic blood pressure'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>value</b>
|
||||||
|
: 60 mmHg
|
||||||
|
<span> (Details: UCUM code mm[Hg] = 'mmHg')</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>interpretation</b>
|
||||||
|
: Below low normal
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
|
||||||
|
code 'L' = 'Low', given as 'low'})</span>
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</text>
|
||||||
|
<identifier>
|
||||||
|
<system value="urn:ietf:rfc:3986" />
|
||||||
|
<value value="urn:uuid:187e0c12-8dd2-67e2-99b2-bf273c878281" />
|
||||||
|
</identifier><!-- demonstrating the use of the baseOn element with a fictive
|
||||||
|
identifier -->
|
||||||
|
<basedOn>
|
||||||
|
<identifier>
|
||||||
|
<system value="https://acme.org/identifiers" />
|
||||||
|
<value value="1234" />
|
||||||
|
</identifier>
|
||||||
|
</basedOn>
|
||||||
|
<status value="final" />
|
||||||
|
<category>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/observation-category" />
|
||||||
|
<code value="vital-signs" />
|
||||||
|
<display value="Vital Signs" />
|
||||||
|
</coding>
|
||||||
|
</category>
|
||||||
|
<code><!-- replaced by 85354-9 <coding> <system value="http://loinc.org"/>
|
||||||
|
<code value="85354-9"/> <display value="Blood pressure systolic & diastolic"/>
|
||||||
|
</coding> -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="85354-9" />
|
||||||
|
<display
|
||||||
|
value="Blood pressure panel with all children optional" />
|
||||||
|
</coding>
|
||||||
|
<text value="Blood pressure systolic & diastolic" />
|
||||||
|
</code>
|
||||||
|
<subject>
|
||||||
|
<reference value="Patient/example" />
|
||||||
|
</subject>
|
||||||
|
<effectiveDateTime value="2012-09-17" />
|
||||||
|
<performer>
|
||||||
|
<reference value="Practitioner/example" />
|
||||||
|
</performer><!-- an interpretation offered to the combination observation
|
||||||
|
generally, it would only be appropriate to offer an interpretation of an
|
||||||
|
observation that has no value if it has "COMP" (component) observations -->
|
||||||
|
<interpretation>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" />
|
||||||
|
<code value="L" />
|
||||||
|
<display value="low" />
|
||||||
|
</coding>
|
||||||
|
<text value="Below low normal" />
|
||||||
|
</interpretation><!-- The BodySite can be captured in a LOINC code but am
|
||||||
|
showing it here to demonstrate populating the element -->
|
||||||
|
<bodySite>
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="368209003" />
|
||||||
|
<display value="Right arm" />
|
||||||
|
</coding>
|
||||||
|
</bodySite>
|
||||||
|
<component><!-- Observations are often coded in multiple code systems. -
|
||||||
|
LOINC provides a very specific code (though not more specific in this particular
|
||||||
|
case) - snomed provides a clinically relevant code that is usually less granular
|
||||||
|
than LOINC - the source system provides its own code, which may be less or
|
||||||
|
more granular than LOINC this is shown here to demonstrate the concept of
|
||||||
|
translations within the codeableConcept datatype. The diastolic code below
|
||||||
|
only has a LOINC code -->
|
||||||
|
<code><!-- LOINC -code -->
|
||||||
|
<!-- removed systolic loinc coide that observation fails <coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="8480-6" />
|
||||||
|
<display value="Systolic blood pressure" />
|
||||||
|
</coding>
|
||||||
|
--> <!-- SNOMED CT Codes -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="271649006" />
|
||||||
|
<display value="Systolic blood pressure" />
|
||||||
|
</coding><!-- Also, a local code specific to the source system -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://acme.org/devices/clinical-codes" />
|
||||||
|
<code value="bp-s" />
|
||||||
|
<display value="Systolic Blood pressure" />
|
||||||
|
</coding>
|
||||||
|
</code>
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="107" />
|
||||||
|
<unit value="mmHg" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mm[Hg]" />
|
||||||
|
</valueQuantity><!-- an interpretation for the individual composite observation -->
|
||||||
|
<interpretation>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" />
|
||||||
|
<code value="N" />
|
||||||
|
<display value="normal" />
|
||||||
|
</coding>
|
||||||
|
<text value="Normal" />
|
||||||
|
</interpretation><!-- Should have a refrange as well -->
|
||||||
|
</component>
|
||||||
|
<component><!-- this codes only has a LOINC code -->
|
||||||
|
<code>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="8462-4" />
|
||||||
|
<display value="Diastolic blood pressure" />
|
||||||
|
</coding>
|
||||||
|
</code>
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="60" />
|
||||||
|
<unit value="mmHg" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mm[Hg]" />
|
||||||
|
</valueQuantity><!-- an interpretation for the individual composite observation -->
|
||||||
|
<interpretation>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" />
|
||||||
|
<code value="L" />
|
||||||
|
<display value="low" />
|
||||||
|
</coding>
|
||||||
|
<text value="Below low normal" />
|
||||||
|
</interpretation><!-- Should have a refrange as well -->
|
||||||
|
</component>
|
||||||
|
</Observation>
|
|
@ -0,0 +1,243 @@
|
||||||
|
<StructureDefinition xmlns="http://hl7.org/fhir">
|
||||||
|
<id value="observation-bp-profile" />
|
||||||
|
<text>
|
||||||
|
<status value="generated" />
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml">reworked official bp profile to use patternCodeableConcept</div>
|
||||||
|
</text>
|
||||||
|
<url value="http://hl7.org/fhir/StructureDefinition/observation-bp-profile" />
|
||||||
|
<version value="4.0.0" />
|
||||||
|
<name value="observation-bp" />
|
||||||
|
<title value="Observation Blood Pressure Profile" />
|
||||||
|
<status value="draft" />
|
||||||
|
<experimental value="false" />
|
||||||
|
<date value="2019-05-06" />
|
||||||
|
<publisher
|
||||||
|
value="Health Level Seven International (Orders and Observations Workgroup)" />
|
||||||
|
<contact>
|
||||||
|
<telecom>
|
||||||
|
<system value="url" />
|
||||||
|
<value
|
||||||
|
value="http://www.hl7.org/Special/committees/orders/index.cfm Orders and Observations" />
|
||||||
|
</telecom>
|
||||||
|
</contact>
|
||||||
|
<description value="FHIR Blood Pressure Profile" />
|
||||||
|
<fhirVersion value="4.0.0" />
|
||||||
|
<mapping>
|
||||||
|
<identity value="workflow" />
|
||||||
|
<uri value="http://hl7.org/fhir/workflow" />
|
||||||
|
<name value="Workflow Pattern" />
|
||||||
|
</mapping>
|
||||||
|
<mapping>
|
||||||
|
<identity value="sct-concept" />
|
||||||
|
<uri value="http://snomed.info/conceptdomain" />
|
||||||
|
<name value="SNOMED CT Concept Domain Binding" />
|
||||||
|
</mapping>
|
||||||
|
<mapping>
|
||||||
|
<identity value="v2" />
|
||||||
|
<uri value="http://hl7.org/v2" />
|
||||||
|
<name value="HL7 v2 Mapping" />
|
||||||
|
</mapping>
|
||||||
|
<mapping>
|
||||||
|
<identity value="rim" />
|
||||||
|
<uri value="http://hl7.org/v3" />
|
||||||
|
<name value="RIM Mapping" />
|
||||||
|
</mapping>
|
||||||
|
<mapping>
|
||||||
|
<identity value="w5" />
|
||||||
|
<uri value="http://hl7.org/fhir/fivews" />
|
||||||
|
<name value="FiveWs Pattern Mapping" />
|
||||||
|
</mapping>
|
||||||
|
<mapping>
|
||||||
|
<identity value="sct-attr" />
|
||||||
|
<uri value="http://snomed.org/attributebinding" />
|
||||||
|
<name value="SNOMED CT Attribute Binding" />
|
||||||
|
</mapping>
|
||||||
|
<kind value="resource" />
|
||||||
|
<abstract value="false" />
|
||||||
|
<type value="Observation" />
|
||||||
|
<baseDefinition
|
||||||
|
value="http://hl7.org/fhir/StructureDefinition/vitalsigns" />
|
||||||
|
<derivation value="constraint" />
|
||||||
|
<differential>
|
||||||
|
<element id="Observation">
|
||||||
|
<path value="Observation" />
|
||||||
|
<short value="FHIR Blood Pressure Profile" />
|
||||||
|
<definition
|
||||||
|
value="This profile defines how to represent Blood Pressure observations in FHIR using a standard LOINC code and UCUM units of measure. This is a grouping structure. It has no value in Observation.valueQuantity but contains at least one component (systolic and/or diastolic)." />
|
||||||
|
<min value="0" />
|
||||||
|
<max value="*" />
|
||||||
|
</element>
|
||||||
|
<element id="Observation.code">
|
||||||
|
<path value="Observation.code" />
|
||||||
|
<short value="Blood Pressure" />
|
||||||
|
<definition value="Blood Pressure" />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
<type>
|
||||||
|
<code value="CodeableConcept" />
|
||||||
|
</type>
|
||||||
|
<patternCodeableConcept>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="85354-9" />
|
||||||
|
</coding>
|
||||||
|
</patternCodeableConcept>
|
||||||
|
<mustSupport value="true" />
|
||||||
|
</element>
|
||||||
|
<element id="Observation.valueQuantity">
|
||||||
|
<path value="Observation.valueQuantity" />
|
||||||
|
<min value="0" />
|
||||||
|
<max value="0" />
|
||||||
|
</element>
|
||||||
|
<element id="Observation.component">
|
||||||
|
<path value="Observation.component" />
|
||||||
|
<slicing>
|
||||||
|
<discriminator>
|
||||||
|
<type value="pattern" />
|
||||||
|
<path value="code" />
|
||||||
|
</discriminator>
|
||||||
|
<rules value="open" />
|
||||||
|
</slicing>
|
||||||
|
<min value="2" />
|
||||||
|
<max value="*" />
|
||||||
|
</element>
|
||||||
|
<element id="Observation.component:SystolicBP">
|
||||||
|
<path value="Observation.component" />
|
||||||
|
<sliceName value="SystolicBP" />
|
||||||
|
<short value="SystolicBP" />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
</element>
|
||||||
|
<element id="Observation.component:SystolicBP.code">
|
||||||
|
<path value="Observation.component.code" />
|
||||||
|
<min value="1" />
|
||||||
|
<patternCodeableConcept>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="8480-6" />
|
||||||
|
</coding>
|
||||||
|
</patternCodeableConcept>
|
||||||
|
</element>
|
||||||
|
<element id="Observation.component:SystolicBP.valueQuantity">
|
||||||
|
<path value="Observation.component.valueQuantity" />
|
||||||
|
<type>
|
||||||
|
<code value="Quantity" />
|
||||||
|
</type>
|
||||||
|
</element>
|
||||||
|
<element
|
||||||
|
id="Observation.component:SystolicBP.valueQuantity.value">
|
||||||
|
<path value="Observation.component.valueQuantity.value" />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
<type>
|
||||||
|
<code value="decimal" />
|
||||||
|
</type>
|
||||||
|
<mustSupport value="true" />
|
||||||
|
</element>
|
||||||
|
<element
|
||||||
|
id="Observation.component:SystolicBP.valueQuantity.unit">
|
||||||
|
<path value="Observation.component.valueQuantity.unit" />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
<type>
|
||||||
|
<code value="string" />
|
||||||
|
</type>
|
||||||
|
<mustSupport value="true" />
|
||||||
|
</element>
|
||||||
|
<element
|
||||||
|
id="Observation.component:SystolicBP.valueQuantity.system">
|
||||||
|
<path value="Observation.component.valueQuantity.system" />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
<type>
|
||||||
|
<code value="uri" />
|
||||||
|
</type>
|
||||||
|
<fixedUri value="http://unitsofmeasure.org" />
|
||||||
|
<mustSupport value="true" />
|
||||||
|
</element>
|
||||||
|
<element
|
||||||
|
id="Observation.component:SystolicBP.valueQuantity.code">
|
||||||
|
<path value="Observation.component.valueQuantity.code" />
|
||||||
|
<short
|
||||||
|
value="Coded responses from the common UCUM units for vital signs value set." />
|
||||||
|
<definition
|
||||||
|
value="Coded responses from the common UCUM units for vital signs value set." />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
<type>
|
||||||
|
<code value="code" />
|
||||||
|
</type>
|
||||||
|
<fixedCode value="mm[Hg]" />
|
||||||
|
<mustSupport value="true" />
|
||||||
|
</element>
|
||||||
|
<element id="Observation.component:DiastolicBP">
|
||||||
|
<path value="Observation.component" />
|
||||||
|
<sliceName value="DiastolicBP" />
|
||||||
|
<short value="DiastolicBP" />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
</element>
|
||||||
|
<element id="Observation.component:DiastolicBP">
|
||||||
|
<path value="Observation.component.code" />
|
||||||
|
<min value="1" />
|
||||||
|
<patternCodeableConcept>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="8462-4" />
|
||||||
|
</coding>
|
||||||
|
</patternCodeableConcept>
|
||||||
|
</element>
|
||||||
|
<element id="Observation.component:DiastolicBP.valueQuantity">
|
||||||
|
<path value="Observation.component.valueQuantity" />
|
||||||
|
<type>
|
||||||
|
<code value="Quantity" />
|
||||||
|
</type>
|
||||||
|
</element>
|
||||||
|
<element
|
||||||
|
id="Observation.component:DiastolicBP.valueQuantity.value">
|
||||||
|
<path value="Observation.component.valueQuantity.value" />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
<type>
|
||||||
|
<code value="decimal" />
|
||||||
|
</type>
|
||||||
|
<mustSupport value="true" />
|
||||||
|
</element>
|
||||||
|
<element
|
||||||
|
id="Observation.component:DiastolicBP.valueQuantity.unit">
|
||||||
|
<path value="Observation.component.valueQuantity.unit" />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
<type>
|
||||||
|
<code value="string" />
|
||||||
|
</type>
|
||||||
|
<mustSupport value="true" />
|
||||||
|
</element>
|
||||||
|
<element
|
||||||
|
id="Observation.component:DiastolicBP.valueQuantity.system">
|
||||||
|
<path value="Observation.component.valueQuantity.system" />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
<type>
|
||||||
|
<code value="uri" />
|
||||||
|
</type>
|
||||||
|
<fixedUri value="http://unitsofmeasure.org" />
|
||||||
|
<mustSupport value="true" />
|
||||||
|
</element>
|
||||||
|
<element
|
||||||
|
id="Observation.component:DiastolicBP.valueQuantity.code">
|
||||||
|
<path value="Observation.component.valueQuantity.code" />
|
||||||
|
<short
|
||||||
|
value="Coded responses from the common UCUM units for vital signs value set." />
|
||||||
|
<definition
|
||||||
|
value="Coded responses from the common UCUM units for vital signs value set." />
|
||||||
|
<min value="1" />
|
||||||
|
<max value="1" />
|
||||||
|
<type>
|
||||||
|
<code value="code" />
|
||||||
|
</type>
|
||||||
|
<fixedCode value="mm[Hg]" />
|
||||||
|
<mustSupport value="true" />
|
||||||
|
</element>
|
||||||
|
</differential>
|
||||||
|
</StructureDefinition>
|
|
@ -0,0 +1,253 @@
|
||||||
|
<Observation xmlns="http://hl7.org/fhir">
|
||||||
|
<!-- extract from https://www.hl7.org/fhir/observation-example-bloodpressure.xml,
|
||||||
|
changed id from blood-pressure to observation-bp-validationfails and added explicit profile
|
||||||
|
reference to http://hl7.org/fhir/StructureDefinition/bp -->
|
||||||
|
<id value="observation-bp-validationfails" />
|
||||||
|
<meta>
|
||||||
|
<profile value="http://hl7.org/fhir/StructureDefinition/bp" />
|
||||||
|
</meta>
|
||||||
|
<text>
|
||||||
|
<status value="generated" />
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<p>
|
||||||
|
<b>Generated Narrative with Details</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>id</b>
|
||||||
|
: blood-pressure
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>meta</b>
|
||||||
|
:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>identifier</b>
|
||||||
|
: urn:uuid:187e0c12-8dd2-67e2-99b2-bf273c878281
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>basedOn</b>
|
||||||
|
:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>status</b>
|
||||||
|
: final
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>category</b>
|
||||||
|
: Vital Signs
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/observation-category code
|
||||||
|
'vital-signs' = 'Vital Signs', given as 'Vital
|
||||||
|
Signs'})</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>code</b>:
|
||||||
|
Blood pressure systolic & diastolic
|
||||||
|
<span>(Details : {LOINC code '85354-9' = 'Blood pressure
|
||||||
|
panel with all children optional', given as 'Blood pressure
|
||||||
|
panel with all children optional'})</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>subject</b>
|
||||||
|
:
|
||||||
|
<a>Patient/example</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>effective</b>
|
||||||
|
: 17/09/2012
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>performer</b>
|
||||||
|
:
|
||||||
|
<a>Practitioner/example</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>interpretation</b>
|
||||||
|
: Below low normal
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
|
||||||
|
code 'L' = 'Low', given as 'low'})</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>bodySite</b>
|
||||||
|
: Right arm
|
||||||
|
<span>(Details : {SNOMED CT code '368209003' = 'Right
|
||||||
|
upper arm', given as 'Right arm'})</span>
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
<b>component</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>code</b>
|
||||||
|
: Systolic blood pressure
|
||||||
|
<span>(Details : {LOINC code '8480-6' = 'Systolic blood
|
||||||
|
pressure', given as 'Systolic blood pressure'};
|
||||||
|
{SNOMED CT code '271649006' = 'Systolic blood
|
||||||
|
pressure', given as 'Systolic blood pressure'};
|
||||||
|
{http://acme.org/devices/clinical-codes code 'bp-s' =
|
||||||
|
'bp-s', given as 'Systolic Blood pressure'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>value</b>
|
||||||
|
: 107 mmHg
|
||||||
|
<span> (Details: UCUM code mm[Hg] = 'mmHg')</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>interpretation</b>
|
||||||
|
: Normal
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
|
||||||
|
code 'N' = 'Normal', given as 'normal'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
<b>component</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>code</b>
|
||||||
|
: Diastolic blood pressure
|
||||||
|
<span>(Details : {LOINC code '8462-4' = 'Diastolic
|
||||||
|
blood pressure', given as 'Diastolic blood pressure'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>value</b>
|
||||||
|
: 60 mmHg
|
||||||
|
<span> (Details: UCUM code mm[Hg] = 'mmHg')</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>interpretation</b>
|
||||||
|
: Below low normal
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
|
||||||
|
code 'L' = 'Low', given as 'low'})</span>
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</text>
|
||||||
|
<identifier>
|
||||||
|
<system value="urn:ietf:rfc:3986" />
|
||||||
|
<value value="urn:uuid:187e0c12-8dd2-67e2-99b2-bf273c878281" />
|
||||||
|
</identifier><!-- demonstrating the use of the baseOn element with a fictive
|
||||||
|
identifier -->
|
||||||
|
<basedOn>
|
||||||
|
<identifier>
|
||||||
|
<system value="https://acme.org/identifiers" />
|
||||||
|
<value value="1234" />
|
||||||
|
</identifier>
|
||||||
|
</basedOn>
|
||||||
|
<status value="final" />
|
||||||
|
<category>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/observation-category" />
|
||||||
|
<code value="vital-signs" />
|
||||||
|
<display value="Vital Signs" />
|
||||||
|
</coding>
|
||||||
|
</category>
|
||||||
|
<code><!-- replaced by 85354-9 <coding> <system value="http://loinc.org"/>
|
||||||
|
<code value="85354-9"/> <display value="Blood pressure systolic & diastolic"/>
|
||||||
|
</coding> -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="85354-9" />
|
||||||
|
<display
|
||||||
|
value="Blood pressure panel with all children optional" />
|
||||||
|
</coding>
|
||||||
|
<text value="Blood pressure systolic & diastolic" />
|
||||||
|
</code>
|
||||||
|
<subject>
|
||||||
|
<reference value="Patient/example" />
|
||||||
|
</subject>
|
||||||
|
<effectiveDateTime value="2012-09-17" />
|
||||||
|
<performer>
|
||||||
|
<reference value="Practitioner/example" />
|
||||||
|
</performer><!-- an interpretation offered to the combination observation
|
||||||
|
generally, it would only be appropriate to offer an interpretation of an
|
||||||
|
observation that has no value if it has "COMP" (component) observations -->
|
||||||
|
<interpretation>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" />
|
||||||
|
<code value="L" />
|
||||||
|
<display value="low" />
|
||||||
|
</coding>
|
||||||
|
<text value="Below low normal" />
|
||||||
|
</interpretation><!-- The BodySite can be captured in a LOINC code but am
|
||||||
|
showing it here to demonstrate populating the element -->
|
||||||
|
<bodySite>
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="368209003" />
|
||||||
|
<display value="Right arm" />
|
||||||
|
</coding>
|
||||||
|
</bodySite>
|
||||||
|
<component><!-- Observations are often coded in multiple code systems. -
|
||||||
|
LOINC provides a very specific code (though not more specific in this particular
|
||||||
|
case) - snomed provides a clinically relevant code that is usually less granular
|
||||||
|
than LOINC - the source system provides its own code, which may be less or
|
||||||
|
more granular than LOINC this is shown here to demonstrate the concept of
|
||||||
|
translations within the codeableConcept datatype. The diastolic code below
|
||||||
|
only has a LOINC code -->
|
||||||
|
<code><!-- LOINC -code -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="8480-6" />
|
||||||
|
<display value="Systolic blood pressure" />
|
||||||
|
</coding><!-- SNOMED CT Codes -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="271649006" />
|
||||||
|
<display value="Systolic blood pressure" />
|
||||||
|
</coding><!-- Also, a local code specific to the source system -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://acme.org/devices/clinical-codes" />
|
||||||
|
<code value="bp-s" />
|
||||||
|
<display value="Systolic Blood pressure" />
|
||||||
|
</coding>
|
||||||
|
</code>
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="107" />
|
||||||
|
<unit value="mmHg" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mm[Hg]" />
|
||||||
|
</valueQuantity><!-- an interpretation for the individual composite observation -->
|
||||||
|
<interpretation>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" />
|
||||||
|
<code value="N" />
|
||||||
|
<display value="normal" />
|
||||||
|
</coding>
|
||||||
|
<text value="Normal" />
|
||||||
|
</interpretation><!-- Should have a refrange as well -->
|
||||||
|
</component>
|
||||||
|
<component><!-- this codes only has a LOINC code -->
|
||||||
|
<code>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="8462-4" />
|
||||||
|
<display value="Diastolic blood pressure" />
|
||||||
|
</coding>
|
||||||
|
</code>
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="60" />
|
||||||
|
<unit value="mmHg" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mm[Hg]" />
|
||||||
|
</valueQuantity><!-- an interpretation for the individual composite observation -->
|
||||||
|
<interpretation>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" />
|
||||||
|
<code value="L" />
|
||||||
|
<display value="low" />
|
||||||
|
</coding>
|
||||||
|
<text value="Below low normal" />
|
||||||
|
</interpretation><!-- Should have a refrange as well -->
|
||||||
|
</component>
|
||||||
|
</Observation>
|
|
@ -0,0 +1,249 @@
|
||||||
|
<Observation xmlns="http://hl7.org/fhir">
|
||||||
|
<!-- extract from https://www.hl7.org/fhir/observation-example-bloodpressure.xml,
|
||||||
|
changed id from blood-pressure to observation-bp -->
|
||||||
|
<id value="observation-bp" />
|
||||||
|
<text>
|
||||||
|
<status value="generated" />
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<p>
|
||||||
|
<b>Generated Narrative with Details</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>id</b>
|
||||||
|
: blood-pressure
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>meta</b>
|
||||||
|
:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>identifier</b>
|
||||||
|
: urn:uuid:187e0c12-8dd2-67e2-99b2-bf273c878281
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>basedOn</b>
|
||||||
|
:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>status</b>
|
||||||
|
: final
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>category</b>
|
||||||
|
: Vital Signs
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/observation-category code
|
||||||
|
'vital-signs' = 'Vital Signs', given as 'Vital
|
||||||
|
Signs'})</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>code</b>:
|
||||||
|
Blood pressure systolic & diastolic
|
||||||
|
<span>(Details : {LOINC code '85354-9' = 'Blood pressure
|
||||||
|
panel with all children optional', given as 'Blood pressure
|
||||||
|
panel with all children optional'})</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>subject</b>
|
||||||
|
:
|
||||||
|
<a>Patient/example</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>effective</b>
|
||||||
|
: 17/09/2012
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>performer</b>
|
||||||
|
:
|
||||||
|
<a>Practitioner/example</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>interpretation</b>
|
||||||
|
: Below low normal
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
|
||||||
|
code 'L' = 'Low', given as 'low'})</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>bodySite</b>
|
||||||
|
: Right arm
|
||||||
|
<span>(Details : {SNOMED CT code '368209003' = 'Right
|
||||||
|
upper arm', given as 'Right arm'})</span>
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
<b>component</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>code</b>
|
||||||
|
: Systolic blood pressure
|
||||||
|
<span>(Details : {LOINC code '8480-6' = 'Systolic blood
|
||||||
|
pressure', given as 'Systolic blood pressure'};
|
||||||
|
{SNOMED CT code '271649006' = 'Systolic blood
|
||||||
|
pressure', given as 'Systolic blood pressure'};
|
||||||
|
{http://acme.org/devices/clinical-codes code 'bp-s' =
|
||||||
|
'bp-s', given as 'Systolic Blood pressure'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>value</b>
|
||||||
|
: 107 mmHg
|
||||||
|
<span> (Details: UCUM code mm[Hg] = 'mmHg')</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>interpretation</b>
|
||||||
|
: Normal
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
|
||||||
|
code 'N' = 'Normal', given as 'normal'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
<b>component</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>code</b>
|
||||||
|
: Diastolic blood pressure
|
||||||
|
<span>(Details : {LOINC code '8462-4' = 'Diastolic
|
||||||
|
blood pressure', given as 'Diastolic blood pressure'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>value</b>
|
||||||
|
: 60 mmHg
|
||||||
|
<span> (Details: UCUM code mm[Hg] = 'mmHg')</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>interpretation</b>
|
||||||
|
: Below low normal
|
||||||
|
<span>(Details :
|
||||||
|
{http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
|
||||||
|
code 'L' = 'Low', given as 'low'})</span>
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</text>
|
||||||
|
<identifier>
|
||||||
|
<system value="urn:ietf:rfc:3986" />
|
||||||
|
<value value="urn:uuid:187e0c12-8dd2-67e2-99b2-bf273c878281" />
|
||||||
|
</identifier><!-- demonstrating the use of the baseOn element with a fictive
|
||||||
|
identifier -->
|
||||||
|
<basedOn>
|
||||||
|
<identifier>
|
||||||
|
<system value="https://acme.org/identifiers" />
|
||||||
|
<value value="1234" />
|
||||||
|
</identifier>
|
||||||
|
</basedOn>
|
||||||
|
<status value="final" />
|
||||||
|
<category>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/observation-category" />
|
||||||
|
<code value="vital-signs" />
|
||||||
|
<display value="Vital Signs" />
|
||||||
|
</coding>
|
||||||
|
</category>
|
||||||
|
<code><!-- replaced by 85354-9 <coding> <system value="http://loinc.org"/>
|
||||||
|
<code value="85354-9"/> <display value="Blood pressure systolic & diastolic"/>
|
||||||
|
</coding> -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="85354-9" />
|
||||||
|
<display
|
||||||
|
value="Blood pressure panel with all children optional" />
|
||||||
|
</coding>
|
||||||
|
<text value="Blood pressure systolic & diastolic" />
|
||||||
|
</code>
|
||||||
|
<subject>
|
||||||
|
<reference value="Patient/example" />
|
||||||
|
</subject>
|
||||||
|
<effectiveDateTime value="2012-09-17" />
|
||||||
|
<performer>
|
||||||
|
<reference value="Practitioner/example" />
|
||||||
|
</performer><!-- an interpretation offered to the combination observation
|
||||||
|
generally, it would only be appropriate to offer an interpretation of an
|
||||||
|
observation that has no value if it has "COMP" (component) observations -->
|
||||||
|
<interpretation>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" />
|
||||||
|
<code value="L" />
|
||||||
|
<display value="low" />
|
||||||
|
</coding>
|
||||||
|
<text value="Below low normal" />
|
||||||
|
</interpretation><!-- The BodySite can be captured in a LOINC code but am
|
||||||
|
showing it here to demonstrate populating the element -->
|
||||||
|
<bodySite>
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="368209003" />
|
||||||
|
<display value="Right arm" />
|
||||||
|
</coding>
|
||||||
|
</bodySite>
|
||||||
|
<component><!-- Observations are often coded in multiple code systems. -
|
||||||
|
LOINC provides a very specific code (though not more specific in this particular
|
||||||
|
case) - snomed provides a clinically relevant code that is usually less granular
|
||||||
|
than LOINC - the source system provides its own code, which may be less or
|
||||||
|
more granular than LOINC this is shown here to demonstrate the concept of
|
||||||
|
translations within the codeableConcept datatype. The diastolic code below
|
||||||
|
only has a LOINC code -->
|
||||||
|
<code><!-- LOINC -code -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="8480-6" />
|
||||||
|
<display value="Systolic blood pressure" />
|
||||||
|
</coding><!-- SNOMED CT Codes -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="271649006" />
|
||||||
|
<display value="Systolic blood pressure" />
|
||||||
|
</coding><!-- Also, a local code specific to the source system -->
|
||||||
|
<coding>
|
||||||
|
<system value="http://acme.org/devices/clinical-codes" />
|
||||||
|
<code value="bp-s" />
|
||||||
|
<display value="Systolic Blood pressure" />
|
||||||
|
</coding>
|
||||||
|
</code>
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="107" />
|
||||||
|
<unit value="mmHg" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mm[Hg]" />
|
||||||
|
</valueQuantity><!-- an interpretation for the individual composite observation -->
|
||||||
|
<interpretation>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" />
|
||||||
|
<code value="N" />
|
||||||
|
<display value="normal" />
|
||||||
|
</coding>
|
||||||
|
<text value="Normal" />
|
||||||
|
</interpretation><!-- Should have a refrange as well -->
|
||||||
|
</component>
|
||||||
|
<component><!-- this codes only has a LOINC code -->
|
||||||
|
<code>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="8462-4" />
|
||||||
|
<display value="Diastolic blood pressure" />
|
||||||
|
</coding>
|
||||||
|
</code>
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="60" />
|
||||||
|
<unit value="mmHg" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mm[Hg]" />
|
||||||
|
</valueQuantity><!-- an interpretation for the individual composite observation -->
|
||||||
|
<interpretation>
|
||||||
|
<coding>
|
||||||
|
<system
|
||||||
|
value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" />
|
||||||
|
<code value="L" />
|
||||||
|
<display value="low" />
|
||||||
|
</coding>
|
||||||
|
<text value="Below low normal" />
|
||||||
|
</interpretation><!-- Should have a refrange as well -->
|
||||||
|
</component>
|
||||||
|
</Observation>
|
|
@ -0,0 +1,103 @@
|
||||||
|
<Observation xmlns="http://hl7.org/fhir">
|
||||||
|
<!-- extract from http://hl7.org/fhir/triglyceride-examples.html, changed
|
||||||
|
id from triglyceride and added explivit profile reference to http://hl7.org/fhir/StructureDefinition/triglyceride
|
||||||
|
and added snomed ct code for triglyceride -->
|
||||||
|
<id value="observation-triglyceride-bad-wrongcode" />
|
||||||
|
<meta>
|
||||||
|
<profile
|
||||||
|
value="http://hl7.org/fhir/StructureDefinition/triglyceride" />
|
||||||
|
</meta>
|
||||||
|
<text>
|
||||||
|
<status value="generated" />
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<p>
|
||||||
|
<b> Generated Narrative with Details</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> id</b>
|
||||||
|
: triglyceride
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> status</b>
|
||||||
|
: final
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> code</b>
|
||||||
|
: Triglyceride
|
||||||
|
<span> (Details : {LOINC code '35217-9' = 'Triglyceride [Mass or
|
||||||
|
Moles/volume] in Serum or Plasma',
|
||||||
|
given as 'Triglyceride
|
||||||
|
[Moles/​volume] in Serum or Plasma'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> subject</b>
|
||||||
|
:
|
||||||
|
<a> Patient/pat2</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> performer</b>
|
||||||
|
:
|
||||||
|
<a> Acme Laboratory, Inc</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> value</b>
|
||||||
|
: 1.3 mmol/L
|
||||||
|
<span> (Details: UCUM code mmol/L = 'mmol/L')</span>
|
||||||
|
</p>
|
||||||
|
<h3> ReferenceRanges</h3>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td> -</td>
|
||||||
|
<td>
|
||||||
|
<b> High</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> *</td>
|
||||||
|
<td>
|
||||||
|
2.0 mmol/L
|
||||||
|
<span> (Details: UCUM code mmol/L = 'mmol/L')</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</text>
|
||||||
|
<status value="final" />
|
||||||
|
<code>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="35200-5" />
|
||||||
|
<display
|
||||||
|
value="Cholest SerPl-msCnc" />
|
||||||
|
</coding>
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="85600001" />
|
||||||
|
<display value="Triacylglycerol" />
|
||||||
|
</coding>
|
||||||
|
<text value="Cholesterol" />
|
||||||
|
</code>
|
||||||
|
<subject>
|
||||||
|
<reference value="Patient/pat2" />
|
||||||
|
</subject>
|
||||||
|
<performer>
|
||||||
|
<reference
|
||||||
|
value="Organization/1832473e-2fe0-452d-abe9-3cdb9879522f" />
|
||||||
|
<display value="Acme Laboratory, Inc" />
|
||||||
|
</performer>
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="1.3" />
|
||||||
|
<unit value="mmol/L" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mmol/L" />
|
||||||
|
</valueQuantity>
|
||||||
|
<referenceRange>
|
||||||
|
<high>
|
||||||
|
<value value="2.0" />
|
||||||
|
<unit value="mmol/L" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mmol/L" />
|
||||||
|
</high>
|
||||||
|
</referenceRange>
|
||||||
|
</Observation>
|
|
@ -0,0 +1,103 @@
|
||||||
|
<Observation xmlns="http://hl7.org/fhir">
|
||||||
|
<!-- extract from http://hl7.org/fhir/triglyceride-examples.html, changed
|
||||||
|
id from triglyceride and added explicit profile reference to http://hl7.org/fhir/StructureDefinition/triglyceride
|
||||||
|
and added snomed ct code for triglyceride -->
|
||||||
|
<id value="observation-triglyceride-good" />
|
||||||
|
<meta>
|
||||||
|
<profile
|
||||||
|
value="http://hl7.org/fhir/StructureDefinition/triglyceride" />
|
||||||
|
</meta>
|
||||||
|
<text>
|
||||||
|
<status value="generated" />
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<p>
|
||||||
|
<b> Generated Narrative with Details</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> id</b>
|
||||||
|
: triglyceride
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> status</b>
|
||||||
|
: final
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> code</b>
|
||||||
|
: Triglyceride
|
||||||
|
<span> (Details : {LOINC code '35217-9' = 'Triglyceride [Mass or
|
||||||
|
Moles/volume] in Serum or Plasma',
|
||||||
|
given as 'Triglyceride
|
||||||
|
[Moles/​volume] in Serum or Plasma'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> subject</b>
|
||||||
|
:
|
||||||
|
<a> Patient/pat2</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> performer</b>
|
||||||
|
:
|
||||||
|
<a> Acme Laboratory, Inc</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> value</b>
|
||||||
|
: 1.3 mmol/L
|
||||||
|
<span> (Details: UCUM code mmol/L = 'mmol/L')</span>
|
||||||
|
</p>
|
||||||
|
<h3> ReferenceRanges</h3>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td> -</td>
|
||||||
|
<td>
|
||||||
|
<b> High</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> *</td>
|
||||||
|
<td>
|
||||||
|
2.0 mmol/L
|
||||||
|
<span> (Details: UCUM code mmol/L = 'mmol/L')</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</text>
|
||||||
|
<status value="final" />
|
||||||
|
<code>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="35217-9" />
|
||||||
|
<display
|
||||||
|
value="Triglyceride [Moles/​volume] in Serum or Plasma" />
|
||||||
|
</coding>
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="85600001" />
|
||||||
|
<display value="Triacylglycerol" />
|
||||||
|
</coding>
|
||||||
|
<text value="Triglyceride" />
|
||||||
|
</code>
|
||||||
|
<subject>
|
||||||
|
<reference value="Patient/pat2" />
|
||||||
|
</subject>
|
||||||
|
<performer>
|
||||||
|
<reference
|
||||||
|
value="Organization/1832473e-2fe0-452d-abe9-3cdb9879522f" />
|
||||||
|
<display value="Acme Laboratory, Inc" />
|
||||||
|
</performer>
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="1.3" />
|
||||||
|
<unit value="mmol/L" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mmol/L" />
|
||||||
|
</valueQuantity>
|
||||||
|
<referenceRange>
|
||||||
|
<high>
|
||||||
|
<value value="2.0" />
|
||||||
|
<unit value="mmol/L" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mmol/L" />
|
||||||
|
</high>
|
||||||
|
</referenceRange>
|
||||||
|
</Observation>
|
|
@ -0,0 +1,108 @@
|
||||||
|
<Observation xmlns="http://hl7.org/fhir">
|
||||||
|
<!-- extract from http://hl7.org/fhir/triglyceride-examples.html, changed
|
||||||
|
id from triglyceride and added explicit profile reference to http://hl7.org/fhir/StructureDefinition/triglyceride
|
||||||
|
and added snomed ct code for triglyceride -->
|
||||||
|
<id value="observation-triglyceride-good2" />
|
||||||
|
<meta>
|
||||||
|
<profile
|
||||||
|
value="http://hl7.org/fhir/StructureDefinition/triglyceride" />
|
||||||
|
</meta>
|
||||||
|
<text>
|
||||||
|
<status value="generated" />
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<p>
|
||||||
|
<b> Generated Narrative with Details</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> id</b>
|
||||||
|
: triglyceride
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> status</b>
|
||||||
|
: final
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> code</b>
|
||||||
|
: Triglyceride
|
||||||
|
<span> (Details : {LOINC code '35217-9' = 'Triglyceride [Mass or
|
||||||
|
Moles/volume] in Serum or Plasma',
|
||||||
|
given as 'Triglyceride
|
||||||
|
[Moles/​volume] in Serum or Plasma'})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> subject</b>
|
||||||
|
:
|
||||||
|
<a> Patient/pat2</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> performer</b>
|
||||||
|
:
|
||||||
|
<a> Acme Laboratory, Inc</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b> value</b>
|
||||||
|
: 1.3 mmol/L
|
||||||
|
<span> (Details: UCUM code mmol/L = 'mmol/L')</span>
|
||||||
|
</p>
|
||||||
|
<h3> ReferenceRanges</h3>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td> -</td>
|
||||||
|
<td>
|
||||||
|
<b> High</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> *</td>
|
||||||
|
<td>
|
||||||
|
2.0 mmol/L
|
||||||
|
<span> (Details: UCUM code mmol/L = 'mmol/L')</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</text>
|
||||||
|
<status value="final" />
|
||||||
|
<code>
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="85600001" />
|
||||||
|
<display value="Triacylglycerol" />
|
||||||
|
</coding>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="35217-9" />
|
||||||
|
<display
|
||||||
|
value="Triglyceride [Moles/​volume] in Serum or Plasma" />
|
||||||
|
</coding>
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct" />
|
||||||
|
<code value="85600001" />
|
||||||
|
<display value="Triacylglycerol" />
|
||||||
|
</coding>
|
||||||
|
<text value="Triglyceride" />
|
||||||
|
</code>
|
||||||
|
<subject>
|
||||||
|
<reference value="Patient/pat2" />
|
||||||
|
</subject>
|
||||||
|
<performer>
|
||||||
|
<reference
|
||||||
|
value="Organization/1832473e-2fe0-452d-abe9-3cdb9879522f" />
|
||||||
|
<display value="Acme Laboratory, Inc" />
|
||||||
|
</performer>
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="1.3" />
|
||||||
|
<unit value="mmol/L" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mmol/L" />
|
||||||
|
</valueQuantity>
|
||||||
|
<referenceRange>
|
||||||
|
<high>
|
||||||
|
<value value="2.0" />
|
||||||
|
<unit value="mmol/L" />
|
||||||
|
<system value="http://unitsofmeasure.org" />
|
||||||
|
<code value="mmol/L" />
|
||||||
|
</high>
|
||||||
|
</referenceRange>
|
||||||
|
</Observation>
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<StructureDefinition xmlns="http://hl7.org/fhir">
|
||||||
|
<id value="slice-by-polymorphic-type2-profile"/>
|
||||||
|
<url value="http://hl7.org/fhir/StructureDefinition/slice-by-polymorphic-type2-profile"/>
|
||||||
|
<name value="SliceByPolymorphicType2Profile"/>
|
||||||
|
<title value="Test slicing by polymorphic type"/>
|
||||||
|
<status value="draft"/>
|
||||||
|
<kind value="resource"/>
|
||||||
|
<abstract value="false"/>
|
||||||
|
<type value="PlanDefinition"/>
|
||||||
|
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/PlanDefinition"/>
|
||||||
|
<derivation value="constraint"/>
|
||||||
|
<differential>
|
||||||
|
<element id="PlanDefinition">
|
||||||
|
<path value="PlanDefinition"/>
|
||||||
|
</element>
|
||||||
|
<element id="PlanDefinition.goal">
|
||||||
|
<path value="PlanDefinition.goal"/>
|
||||||
|
</element>
|
||||||
|
<element id="PlanDefinition.goal.target">
|
||||||
|
<path value="PlanDefinition.goal.target"/>
|
||||||
|
</element>
|
||||||
|
<element id="PlanDefinition.goal.target.detail[x]">
|
||||||
|
<path value="PlanDefinition.goal.target.detail[x]"/>
|
||||||
|
<type>
|
||||||
|
<code value="CodeableConcept"/>
|
||||||
|
</type>
|
||||||
|
<type>
|
||||||
|
<code value="Range"/>
|
||||||
|
</type>
|
||||||
|
</element>
|
||||||
|
<element id="PlanDefinition.goal.target.detailCodeableConcept">
|
||||||
|
<path value="PlanDefinition.goal.target.detailCodeableConcept"/>
|
||||||
|
<type>
|
||||||
|
<code value="CodeableConcept"/>
|
||||||
|
</type>
|
||||||
|
<mustSupport value="true"/>
|
||||||
|
</element>
|
||||||
|
</differential>
|
||||||
|
</StructureDefinition>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--<PlanDefinition xmlns="http://hl7.org/fhir" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hl7.org/fhir ../../../../../../FHIR/schema/fhir-single.xsd">-->
|
||||||
|
<PlanDefinition xmlns="http://hl7.org/fhir">
|
||||||
|
<id value="slice-by-polymorphic-type2"/>
|
||||||
|
<status value="active"/>
|
||||||
|
<goal>
|
||||||
|
<description>
|
||||||
|
<text value="Some goal"/>
|
||||||
|
</description>
|
||||||
|
<target>
|
||||||
|
<detailCodeableConcept>
|
||||||
|
<text value="Some Text"/>
|
||||||
|
</detailCodeableConcept>
|
||||||
|
</target>
|
||||||
|
</goal>
|
||||||
|
</PlanDefinition>
|
Loading…
Reference in New Issue