Merge pull request #1271 from hapifhir/gg-202304-more-snapshot

Gg 202304 more snapshot
This commit is contained in:
Grahame Grieve 2023-05-24 08:44:27 +10:00 committed by GitHub
commit 8f3367772c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 198 additions and 49 deletions

View File

@ -2,11 +2,16 @@
* Snapshot Generation Changes:
** Check for slicenames without any slicing
** Check that slice names are unique
** Check for additional slicing rules in a set of slices
** Check that the minimum cardinality of a set of slices is correct
* Clean up duplicate errors when dates/dateTimes/instants have invalid formats
* Handle unknown code systems consistently when validating coded elements
* Handle sub-slicing case where slice matches both the slice definition and the sub-slice definition
## Other code changes
* Add support for R4B to loader
* Change type if cache-id parameter

View File

@ -174,17 +174,13 @@ public class ProfilePathProcessor {
// in the simple case, source is not sliced.
if (!currentBase.hasSlicing() || currentBasePath.equals(getSlicing().getPath()))
{
ElementDefinition currentRes = processSimplePath(currentBase, currentBasePath, diffMatches, typeList,
cursors
);
ElementDefinition currentRes = processSimplePath(currentBase, currentBasePath, diffMatches, typeList, cursors);
if (res == null) {
res = currentRes;
}
}
else {
processPathWithSlicedBase(currentBase, currentBasePath, diffMatches, typeList,
cursors
);
processPathWithSlicedBase(currentBase, currentBasePath, diffMatches, typeList, cursors);
}
}

View File

@ -135,6 +135,7 @@ public class ProfileUtilities extends TranslatingUtilities {
public class ElementDefinitionCounter {
int count = 0;
ElementDefinition focus;
Set<String> names = new HashSet<>();
public ElementDefinitionCounter(ElementDefinition ed) {
focus = ed;
@ -142,15 +143,16 @@ public class ProfileUtilities extends TranslatingUtilities {
public int update() {
if (count > focus.getMin()) {
int was = focus.getMin();
focus.setMin(count);
return was;
return count;
}
return -1;
}
public void count(ElementDefinition ed) {
public boolean count(ElementDefinition ed, String name) {
count = count + ed.getMin();
boolean ok = !names.contains(name);
names.add(name);
return ok;
}
public ElementDefinition getFocus() {
@ -725,13 +727,13 @@ public class ProfileUtilities extends TranslatingUtilities {
if (tn.contains("/")) {
tn = tn.substring(tn.lastIndexOf("/")+1);
}
System.out.println("Check slicing for "+derived.getVersionedUrl());
// System.out.println("Check slicing for "+derived.getVersionedUrl());
Map<String, ElementDefinitionCounter> slices = new HashMap<>();
int i = 0;
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
if (ed.hasSlicing()) {
slices.put(ed.getPath(), new ElementDefinitionCounter(ed));
System.out.println("Entering slicing for "+ed.getPath()+" ["+i+"]");
// System.out.println("Entering slicing for "+ed.getPath()+" ["+i+"]");
} else {
Set<String> toRemove = new HashSet<>();
for (String s : slices.keySet()) {
@ -740,13 +742,14 @@ public class ProfileUtilities extends TranslatingUtilities {
}
}
for (String s : toRemove) {
int was = slices.get(s).update();
if (was > -1) {
String msg = "The slice definition for "+slices.get(s).getFocus().getId()+" had a minimum of "+was+" but the slices added up to a minimum of "+slices.get(s).getFocus().getMin()+" so the value has been adjusted in the snapshot";
System.out.println(msg);
int count = slices.get(s).update();
if (count > -1) {
String msg = "The slice definition for "+slices.get(s).getFocus().getId()+" has a minimum of "+slices.get(s).getFocus().getMin()+" but the slices add up to a minimum of "+count;
//+" so the value has been adjusted in the snapshot"; we don't adjust it because of downstream effects. But if it's for publication, they better get it right.
// System.out.println(msg);
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), msg, forPublication ? ValidationMessage.IssueSeverity.ERROR : ValidationMessage.IssueSeverity.INFORMATION));
}
System.out.println("Exiting slicing for "+s+" at "+ed.getPath()+" ["+i+"]");
// System.out.println("Exiting slicing for "+s+" at "+ed.getPath()+" ["+i+"]");
slices.remove(s);
}
}
@ -758,7 +761,10 @@ public class ProfileUtilities extends TranslatingUtilities {
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
}
if (ed.hasSliceName() && slices.containsKey(ed.getPath())) {
slices.get(ed.getPath()).count(ed);
if (!slices.get(ed.getPath()).count(ed, ed.getSliceName())) {
String msg = "Duplicate slice name "+ed.getSliceName()+" on "+ed.getId()+" (["+i+"])";
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
}
}
i++;
}
@ -2043,10 +2049,15 @@ public class ProfileUtilities extends TranslatingUtilities {
}
// Before applying changes, apply them to what's in the profile
StructureDefinition profile = null;
if (base.hasSliceName())
if (base.hasSliceName()) {
profile = base.getType().size() == 1 && base.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, base.getTypeFirstRep().getProfile().get(0).getValue(), srcSD) : null;
if (profile==null)
}
if (profile==null) {
profile = source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, source.getTypeFirstRep().getProfile().get(0).getValue(), derivedSrc) : null;
if (profile != null && !"Extension".equals(profile.getType())) {
profile = null;
}
}
if (profile != null) {
ElementDefinition e = profile.getSnapshot().getElement().get(0);
String webroot = profile.getUserString("webroot");
@ -2157,7 +2168,7 @@ public class ProfileUtilities extends TranslatingUtilities {
if (derived.hasMinElement()) {
if (!Base.compareDeep(derived.getMinElement(), base.getMinElement(), false)) {
if (derived.getMin() < base.getMin() && !derived.hasSliceName()) // in a slice, minimum cardinality rules do not apply
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived min ("+Integer.toString(derived.getMin())+") cannot be less than base min ("+Integer.toString(base.getMin())+")", ValidationMessage.IssueSeverity.ERROR));
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived min ("+Integer.toString(derived.getMin())+") cannot be less than the base min ("+Integer.toString(base.getMin())+") in "+srcSD.getVersionedUrl(), ValidationMessage.IssueSeverity.ERROR));
base.setMinElement(derived.getMinElement().copy());
} else if (trimDifferential)
derived.setMinElement(null);
@ -2168,7 +2179,7 @@ public class ProfileUtilities extends TranslatingUtilities {
if (derived.hasMaxElement()) {
if (!Base.compareDeep(derived.getMaxElement(), base.getMaxElement(), false)) {
if (isLargerMax(derived.getMax(), base.getMax()))
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived max ("+derived.getMax()+") cannot be greater than base max ("+base.getMax()+")", ValidationMessage.IssueSeverity.ERROR));
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived max ("+derived.getMax()+") cannot be greater than the base max ("+base.getMax()+")", ValidationMessage.IssueSeverity.ERROR));
base.setMaxElement(derived.getMaxElement().copy());
} else if (trimDifferential)
derived.setMaxElement(null);

View File

@ -73,6 +73,7 @@ import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
import org.hl7.fhir.r5.model.IdType;
import org.hl7.fhir.r5.model.ImplementationGuide;
import org.hl7.fhir.r5.model.Library;
import org.hl7.fhir.r5.model.Measure;
@ -868,7 +869,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
// if that failed, we try to expand on the server
if (addDependentResources(p, vs)) {
p.addParameter().setName("cache-id").setValue(new StringType(tcc.getCacheId()));
p.addParameter().setName("cache-id").setValue(new IdType(tcc.getCacheId()));
}
if (noTerminologyServer) {
@ -1147,7 +1148,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
boolean cached = addDependentResources(p, vs);
if (cached) {
p.addParameter().setName("cache-id").setValue(new StringType(tcc.getCacheId()));
p.addParameter().setName("cache-id").setValue(new IdType(tcc.getCacheId()));
}
return p;
}
@ -1276,7 +1277,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
addDependentResources(pin, vs);
}
if (cache) {
pin.addParameter().setName("cache-id").setValue(new StringType(tcc.getCacheId()));
pin.addParameter().setName("cache-id").setValue(new IdType(tcc.getCacheId()));
}
for (ParametersParameterComponent pp : pin.getParameter()) {
if (pp.getName().equals("profile")) {
@ -1917,6 +1918,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
private Set<String> notCanonical = new HashSet<String>();
protected IWorkerContextManager.IPackageLoadingTracker packageTracker;
private boolean forPublication;
@Override
public Resource fetchResourceById(String type, String uri) {
@ -2467,4 +2469,13 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
// TODO Auto-generated method stub
return new PEBuilder(this, elementProps, fixedProps);
}
public boolean isForPublication() {
return forPublication;
}
public void setForPublication(boolean value) {
forPublication = value;
}
}

View File

@ -274,6 +274,7 @@ public class ContextUtilities implements ProfileKnowledgeProvider {
ProfileUtilities pu = new ProfileUtilities(context, msgs, this);
pu.setAutoFixSliceNames(true);
pu.setThrowException(false);
pu.setForPublication(context.isForPublication());
if (xverManager == null) {
xverManager = new XVerExtensionManager(context);
}
@ -282,8 +283,9 @@ public class ContextUtilities implements ProfileKnowledgeProvider {
pu.sortDifferential(sd, p, p.getUrl(), errors, true);
}
pu.setDebug(false);
for (String err : errors)
for (String err : errors) {
msgs.add(new ValidationMessage(Source.ProfileValidator, IssueType.EXCEPTION, p.getWebPath(), "Error sorting Differential: "+err, ValidationMessage.IssueSeverity.ERROR));
}
pu.generateSnapshot(sd, p, p.getUrl(), sd.getUserString("webroot"), p.getName());
for (ValidationMessage msg : msgs) {
if ((!ignoreProfileErrors && msg.getLevel() == ValidationMessage.IssueSeverity.ERROR) || msg.getLevel() == ValidationMessage.IssueSeverity.FATAL)

View File

@ -941,4 +941,6 @@ public interface IWorkerContext {
public PEBuilder getProfiledElementBuilder(PEElementPropertiesPolicy elementProps, boolean fixedProps);
public boolean isForPublication();
public void setForPublication(boolean value);
}

View File

@ -544,7 +544,7 @@ public class Coding extends DataType implements IBaseCoding, ICompositeType, ICo
base = base+"|"+getVersion();
base = base + "#"+getCode();
if (hasDisplay())
base = base+": "+getDisplay();
base = base+": '"+getDisplay()+"'";
return base;
}

View File

@ -127,7 +127,7 @@ public class ResourceUtilities {
public static String getLink(Bundle feed, String rel) {
for (BundleLinkComponent link : feed.getLink()) {
if (link.getRelation().equals(rel))
if (link.getRelation().toCode().equals(rel))
return link.getUrl();
}
return null;

View File

@ -1951,6 +1951,30 @@ public class Utilities {
return p;
}
public static String stripAllPara(String p) {
if (noString(p)) {
return "";
}
p = p.trim();
if (p.startsWith("<p>")) {
p = p.substring(3);
}
if (p.endsWith("</p>")) {
p = p.substring(0, p.length()-4);
}
p = p.replace("</p>", " ");
p = p.replace("<p>", "");
while (p.contains("<p ")) {
int start = p.indexOf("<p ");
int end = start;
while (end < p.length() && p.charAt(end) != '>') {
end++;
}
p = p.substring(start, end);
}
return p;
}
//public static boolean !isWhitespace(String s) {

View File

@ -869,6 +869,7 @@ public class I18nConstants {
public static final String ED_PATH_WRONG_TYPE_MATCH = "ED_PATH_WRONG_TYPE_MATCH";
public static final String ATTEMPT_TO_CHANGE_SLICING = "ATTEMPT_TO_CHANGE_SLICING";
public static final String REPEAT_SLICING_IGNORED = "REPEAT_SLICING_IGNORED";
public static final String SD_ELEMENT_NOT_IN_CONSTRAINT = "SD_ELEMENT_NOT_IN_CONSTRAINT";
}

View File

@ -923,4 +923,4 @@ SD_CONTEXT_SHOULD_NOT_BE_ELEMENT = Review the extension type: extensions should
ED_PATH_WRONG_TYPE_MATCH = The path must be ''{0}'' not ''{1}'' when the type list is not constrained
ATTEMPT_TO_CHANGE_SLICING = The element at {0} defines the slicing {1} but then an element in the slicing {2} tries to redefine the slicing to {3}
REPEAT_SLICING_IGNORED = The element at {0} defines the slicing but then an element in the slicing {2} repeats it, which is ignored
SD_ELEMENT_NOT_IN_CONSTRAINT = The element definition for {1} has a property {0} which is not allowed in a profile

View File

@ -5968,8 +5968,23 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
}
if (match) {
boolean update = true;
boolean isOk = ei.definition == null || ei.definition == slicer || (ei.definition.getPath().endsWith("[x]") && ed.getPath().startsWith(ei.definition.getPath().replace("[x]", "")));
if (!isOk) {
// is this a subslice? then we put it in as a replacement
String existingName = ei.definition == null || !ei.definition.hasSliceName() ? null : ei.definition.getSliceName();
String matchingName = ed.hasSliceName() ? ed.getSliceName() : null;
if (existingName != null && matchingName != null) {
if (matchingName.startsWith(existingName+"/")) {
isOk = true;
} else if (existingName.startsWith(matchingName+"/")) {
update = false;
isOk = true;
}
}
}
if (rule(errors, NO_RULE_DATE, IssueType.INVALID, ei.line(), ei.col(), ei.getPath(), isOk, I18nConstants.VALIDATION_VAL_PROFILE_MATCHMULTIPLE, profile.getVersionedUrl(), (ei.definition == null || !ei.definition.hasSliceName() ? "" : ei.definition.getSliceName()), (ed.hasSliceName() ? ed.getSliceName() : ""))) {
if (update) {
ei.definition = ed;
if (ei.slice == null) {
ei.index = i;
@ -5978,6 +5993,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
ei.sliceindex = i - (sliceOffset + 1);
}
}
}
} else if (childUnsupportedSlicing) {
problematicPaths.add(ed.getPath());
}

View File

@ -127,14 +127,16 @@ public class StructureDefinitionValidator extends BaseValidator {
rule(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.ERROR_GENERATING_SNAPSHOT, e.getMessage());
ok = false;
}
List<Element> differentials = src.getChildrenByName("differential");
List<Element> snapshots = src.getChildrenByName("snapshot");
boolean logical = "logical".equals(src.getNamedChildValue("kind"));
boolean constraint = "constraint".equals(src.getNamedChildValue("derivation"));
for (Element differential : differentials) {
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd, typeName, logical) && ok;
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd, typeName, logical, constraint) && ok;
}
for (Element snapshot : snapshots) {
ok = validateElementList(errors, snapshot, stack.push(snapshot, -1, null, null), true, true, sd, typeName, logical) && ok;
ok = validateElementList(errors, snapshot, stack.push(snapshot, -1, null, null), true, true, sd, typeName, logical, constraint) && ok;
}
return ok;
}
@ -174,18 +176,18 @@ public class StructureDefinitionValidator extends BaseValidator {
}
}
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical) {
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint) {
boolean ok = true;
List<Element> elements = elementList.getChildrenByName("element");
int cc = 0;
for (Element element : elements) {
ok = validateElementDefinition(errors, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd, typeName, logical) && ok;
ok = validateElementDefinition(errors, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd, typeName, logical, constraint) && ok;
cc++;
}
return ok;
}
private boolean validateElementDefinition(List<ValidationMessage> errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical) {
private boolean validateElementDefinition(List<ValidationMessage> errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint) {
boolean ok = true;
boolean typeMustSupport = false;
String path = element.getNamedChildValue("path");
@ -194,6 +196,8 @@ public class StructureDefinitionValidator extends BaseValidator {
rule(errors, "2023-01-17", IssueType.INVALID, stack.getLiteralPath(), path.contains(".") || !element.hasChild("slicing"), I18nConstants.SD_NO_SLICING_ON_ROOT, path);
}
rule(errors, "2023-05-22", IssueType.NOTFOUND, stack.getLiteralPath(), snapshot || !constraint || !element.hasChild("meaningWhenMissing") || meaningWhenMissingAllowed(element), I18nConstants.SD_ELEMENT_NOT_IN_CONSTRAINT, "meaningWhenMissing", path);
List<Element> types = element.getChildrenByName("type");
Set<String> typeCodes = new HashSet<>();
Set<String> characteristics = new HashSet<>();
@ -312,6 +316,12 @@ public class StructureDefinitionValidator extends BaseValidator {
return ok;
}
private boolean meaningWhenMissingAllowed(Element element) {
// allowed to use meaningWhenMissing on the root of an element to say what it means when the extension
// is not present.
return "Extension".equals(element.getPath()) || (element.getPath().endsWith(".extension"));
}
private boolean addCharacteristics(Set<String> set, String tc) {
switch (tc) {
case "boolean" : return addCharacteristicsForType(set);

View File

@ -180,7 +180,7 @@ public class SnapShotGenerationXTests {
else
source = (StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", id + "-input.xml"));
if (!fail)
expected = (StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", id + "-expected.xml"));
expected = (StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", id + "-output.xml"));
if (!Utilities.noString(include))
included = (StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", include + ".xml"));
if (!Utilities.noString(register)) {
@ -471,8 +471,7 @@ public class SnapShotGenerationXTests {
pu.sortDifferential(base, test.getOutput(), test.getOutput().getUrl(), errors, false);
if (!errors.isEmpty())
throw new FHIRException(errors.get(0));
IOUtils.copy(TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", test.getId() + "-expected.xml"), new FileOutputStream(UtilitiesXTests.tempFile("snapshot", test.getId() + "-expected.xml")));
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(UtilitiesXTests.tempFile("snapshot", test.getId() + "-actual.xml")), test.getOutput());
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(UtilitiesXTests.tempFile("snapshot", test.getId() + "-output.xml")), test.getOutput());
Assertions.assertTrue(test.expected.equalsDeep(test.output), "Output does not match expected");
}
@ -542,11 +541,10 @@ public class SnapShotGenerationXTests {
if (!fail) {
test.output = output;
UtilitiesXTests.context(version).cacheResource(output);
File dst = new File(UtilitiesXTests.tempFile("snapshot", test.getId() + "-expected.xml"));
File dst = new File(UtilitiesXTests.tempFile("snapshot", test.getId() + "-output.xml"));
if (dst.exists())
dst.delete();
IOUtils.copy(TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", test.getId() + "-expected.xml"), new FileOutputStream(dst));
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(UtilitiesXTests.tempFile("snapshot", test.getId() + "-actual.xml")), output);
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(UtilitiesXTests.tempFile("snapshot", test.getId() + "-output.xml")), output);
StructureDefinition t1 = test.expected.copy();
t1.setText(null);
StructureDefinition t2 = test.output.copy();

View File

@ -107,7 +107,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
}
public final static boolean PRINT_OUTPUT_TO_CONSOLE = true;
private static final boolean BUILD_NEW = false;
private static final boolean BUILD_NEW = true;
private static final boolean CLONE = true;
@Parameters(name = "{index}: id {0}")

View File

@ -3443,3 +3443,22 @@ v: {
"class" : "SERVER_ERROR"
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://loinc.org",
"version" : "2.71",
"code" : "29463-7",
"display" : "Body weight"
}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Body weight",
"code" : "29463-7",
"system" : "http://loinc.org",
"version" : "2.74"
}
-------------------------------------------------------------------------------------

View File

@ -2150,3 +2150,41 @@ v: {
"version" : "http://snomed.info/sct/900000000000207008/version/20230131"
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://snomed.info/sct",
"version" : "http://snomed.info/sct/900000000000207008/version/20210731",
"code" : "27113001",
"display" : "Body weight (observable entity)"
}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Body weight",
"code" : "27113001",
"system" : "http://snomed.info/sct",
"version" : "http://snomed.info/sct/900000000000207008/version/20210731"
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://snomed.info/sct",
"version" : "http://snomed.info/sct/900000000000207008/version/20210731",
"code" : "38266002",
"display" : "Entire body as a whole (body structure)"
}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Entire body as a whole",
"code" : "38266002",
"system" : "http://snomed.info/sct",
"version" : "http://snomed.info/sct/900000000000207008/version/20210731"
}
-------------------------------------------------------------------------------------

View File

@ -420,3 +420,19 @@ v: {
"version" : "2.0.1"
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://unitsofmeasure.org",
"code" : "KG"
}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"severity" : "error",
"error" : "Error processing Unit: 'KG': The unit \"KG\" is unknown at character 1; Unknown Code 'KG' in the system 'http://unitsofmeasure.org'; The provided code http://unitsofmeasure.org#KG is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
"class" : "UNKNOWN"
}
-------------------------------------------------------------------------------------