2023 10 gg cda parsing fix 2 (#1451)
* fix xml output to deal with namespaces properly * Improve rendering or xml_no_order * add command line demo app * fix CDA parsing error for sdtc:raceCode * Fix error message * Bump test case version --------- Co-authored-by: Grahame Grieve <grahameg@gmail.ccom> Co-authored-by: dotasek <dotasek.dev@gmail.com>
This commit is contained in:
parent
ff29b09083
commit
752ab7a3d1
|
@ -0,0 +1,335 @@
|
|||
package org.hl7.fhir.r4.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r4.context.SimpleWorkerContext;
|
||||
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.BooleanType;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.r4.model.CapabilityStatement;
|
||||
import org.hl7.fhir.r4.model.CodeType;
|
||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||
import org.hl7.fhir.r4.model.Coding;
|
||||
import org.hl7.fhir.r4.model.Condition;
|
||||
import org.hl7.fhir.r4.model.HumanName;
|
||||
import org.hl7.fhir.r4.model.Immunization;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Period;
|
||||
import org.hl7.fhir.r4.model.Procedure;
|
||||
import org.hl7.fhir.r4.model.Property;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.Type;
|
||||
import org.hl7.fhir.r4.utils.client.FHIRToolingClient;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
|
||||
public class CmdLineApp {
|
||||
|
||||
private FHIRToolingClient client;
|
||||
private String currentId;
|
||||
private Resource currentResource;
|
||||
private SimpleWorkerContext context;
|
||||
private FHIRPathEngine fpe;
|
||||
|
||||
public static void main(String[] args) throws IOException, Exception {
|
||||
new CmdLineApp().execute();
|
||||
}
|
||||
|
||||
private void execute() throws IOException {
|
||||
System.out.print("Loading...");
|
||||
NpmPackage npm = new FilesystemPackageCacheManager(true).loadPackage("hl7.fhir.r4.core");
|
||||
context = SimpleWorkerContext.fromPackage(npm);
|
||||
fpe = new FHIRPathEngine(context);
|
||||
System.out.println(" Done");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||
genMenu();
|
||||
boolean finished = false;
|
||||
do {
|
||||
System.out.print("> ");
|
||||
String cmd = reader.readLine();
|
||||
String[] p = cmd.split("\\s+");
|
||||
try {
|
||||
if (p.length == 1 && p[0].equals("x")) {
|
||||
finished = true;
|
||||
} else if (p.length == 1 && p[0].equals("?")) {
|
||||
genMenu();
|
||||
} else if (p.length >= 1 && p[0].equals("c")) {
|
||||
if (p.length == 1) {
|
||||
connectToServer("http://hapi.fhir.org/baseR4");
|
||||
} else {
|
||||
connectToServer(p[1]);
|
||||
}
|
||||
} else if (p.length >= 1 && p[0].equals("imm")) {
|
||||
if (p.length == 1) {
|
||||
if (currentResource == null || !(currentResource instanceof Patient)) {
|
||||
throw new FHIRException("Current resource must be a patient for this command");
|
||||
}
|
||||
getImmunizations();
|
||||
} else {
|
||||
select("Immunization", p[1]);
|
||||
}
|
||||
} else if (p.length >= 1 && p[0].equals("cnd")) {
|
||||
if (p.length == 1) {
|
||||
if (currentResource == null || !(currentResource instanceof Patient)) {
|
||||
throw new FHIRException("Current resource must be a patient for this command");
|
||||
}
|
||||
getConditions();
|
||||
} else {
|
||||
select("Condition", p[1]);
|
||||
}
|
||||
} else if (p.length >= 1 && p[0].equals("prc")) {
|
||||
if (p.length == 1) {
|
||||
if (currentResource == null || !(currentResource instanceof Patient)) {
|
||||
throw new FHIRException("Current resource must be a patient for this command");
|
||||
}
|
||||
getProcedures();
|
||||
} else {
|
||||
select("Procedure", p[1]);
|
||||
}
|
||||
} else if (p.length >= 1 && p[0].equals("v")) {
|
||||
if (p.length == 1) {
|
||||
viewResource();
|
||||
} else {
|
||||
viewResource(p[1]);
|
||||
}
|
||||
} else if (p.length >= 2 && p[0].equals("s")) {
|
||||
search(p);
|
||||
} else if (p.length >= 2 && p[0].equals("p")) {
|
||||
select("Patient", p[1]);
|
||||
} else if (p.length == 3 && p[0].equals("e")) {
|
||||
edit(p[1], p[2]);
|
||||
} else {
|
||||
System.out.println("Command unknown or not understood: "+cmd);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error executing command "+p[0]+": "+e.getMessage());
|
||||
}
|
||||
} while (!finished);
|
||||
|
||||
System.out.println("Finished!");
|
||||
}
|
||||
|
||||
private void getImmunizations() {
|
||||
|
||||
Bundle bnd = client.search("Immunization", "?patient="+currentId);
|
||||
System.out.println(""+bnd.getTotal()+" Immunizations found. Printing "+bnd.getEntry().size());
|
||||
|
||||
for (BundleEntryComponent be : bnd.getEntry()) {
|
||||
Resource imm = be.getResource();
|
||||
System.out.println(summary(imm));
|
||||
}
|
||||
}
|
||||
|
||||
private void getProcedures() {
|
||||
|
||||
Bundle bnd = client.search("Procedure", "?patient="+currentId);
|
||||
System.out.println(""+bnd.getTotal()+" Procedures found. Printing "+bnd.getEntry().size());
|
||||
|
||||
for (BundleEntryComponent be : bnd.getEntry()) {
|
||||
Resource imm = be.getResource();
|
||||
System.out.println(summary(imm));
|
||||
}
|
||||
}
|
||||
|
||||
private void getConditions() {
|
||||
|
||||
Bundle bnd = client.search("Condition", "?patient="+currentId);
|
||||
System.out.println(""+bnd.getTotal()+" Conditions found. Printing "+bnd.getEntry().size());
|
||||
|
||||
for (BundleEntryComponent be : bnd.getEntry()) {
|
||||
Resource imm = be.getResource();
|
||||
System.out.println(summary(imm));
|
||||
}
|
||||
}
|
||||
|
||||
private void edit(String path, String value) {
|
||||
if (path.contains(".")) {
|
||||
List<Base> list = fpe.evaluate(currentResource, fpe.parse(path.substring(0, path.lastIndexOf("."))));
|
||||
if (list.size() == 1) {
|
||||
path = path.substring(path.lastIndexOf(".")+1);
|
||||
Property p = list.get(0).getNamedProperty(path);
|
||||
Base b = makeValue(p, value);
|
||||
list.get(0).setProperty(path, b);
|
||||
} else {
|
||||
throw new FHIRException("Unable to set value at "+path+": "+list.size()+" matches");
|
||||
}
|
||||
} else {
|
||||
Property p = currentResource.getNamedProperty(path);
|
||||
Base b = makeValue(p, value);
|
||||
currentResource.setProperty(path, b);
|
||||
}
|
||||
currentResource = client.update(currentResource);
|
||||
}
|
||||
|
||||
private Base makeValue(Property p, String value) {
|
||||
switch (p.getTypeCode()) {
|
||||
case "boolean" : return new BooleanType(value);
|
||||
case "code" : return new CodeType(value);
|
||||
case "string" : return new StringType(value);
|
||||
}
|
||||
throw new FHIRException("Unhandled type "+p.getTypeCode());
|
||||
}
|
||||
|
||||
private void viewResource(String path) {
|
||||
System.out.println("Current Resource, query = "+path);
|
||||
List<Base> list = fpe.evaluate(currentResource, fpe.parse(path));
|
||||
for (Base b : list) {
|
||||
System.out.println(b.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void viewResource() throws IOException {
|
||||
System.out.println("Current Resource:");
|
||||
System.out.println(new JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(currentResource));
|
||||
}
|
||||
|
||||
private void select(String type, String id) {
|
||||
if (type.equals("Patient")) {
|
||||
currentResource = client.fetchResource(Patient.class, id);
|
||||
} else if (type.equals("Immunization")) {
|
||||
currentResource = client.fetchResource(Immunization.class, id);
|
||||
} else if (type.equals("Condition")) {
|
||||
currentResource = client.fetchResource(Condition.class, id);
|
||||
} else if (type.equals("Procedure")) {
|
||||
currentResource = client.fetchResource(Procedure.class, id);
|
||||
} else {
|
||||
throw new FHIRException("Unhandled type "+type);
|
||||
}
|
||||
currentId = type+"/"+id;
|
||||
System.out.println("Resource = "+currentId+" "+summary(currentResource));
|
||||
}
|
||||
|
||||
private String summary(Resource r) {
|
||||
if (r instanceof Patient) {
|
||||
Patient pat = (Patient) r;
|
||||
return pat.getIdBase()+" "+pat.getGender()+" "+pat.getBirthDateElement().asStringValue()+" "+name(pat);
|
||||
}
|
||||
if (r instanceof Immunization) {
|
||||
Immunization imm = (Immunization) r;
|
||||
return imm.getIdBase()+" "+imm.getOccurrenceDateTimeType().asStringValue()+" "+code(imm.getVaccineCode())+" "+imm.getLotNumber()+" ("+imm.getStatus()+")";
|
||||
}
|
||||
if (r instanceof Condition) {
|
||||
Condition cnd = (Condition) r;
|
||||
return cnd.getIdBase()+" "+code(cnd.getClinicalStatus())+" "+code(cnd.getVerificationStatus())+" "+code(cnd.getCode())+" "+cnd.getRecordedDateElement().asStringValue();
|
||||
}
|
||||
if (r instanceof Procedure) {
|
||||
Procedure prc = (Procedure) r;
|
||||
return prc.getIdBase()+" "+prc.getStatusElement().asStringValue()+" "+code(prc.getCode())+" "+code(prc.getCode())+" "+dt(prc.getPerformed());
|
||||
}
|
||||
return "??";
|
||||
}
|
||||
|
||||
private String dt(Type type) {
|
||||
if (type == null) {
|
||||
return "";
|
||||
}
|
||||
if (type.isPrimitive()) {
|
||||
return type.primitiveValue();
|
||||
}
|
||||
if (type instanceof Period) {
|
||||
Period pd = (Period) type;
|
||||
return pd.getStartElement().asStringValue()+" -> "+pd.getEndElement().asStringValue();
|
||||
}
|
||||
return "??";
|
||||
}
|
||||
|
||||
private String code(CodeableConcept cc) {
|
||||
for (Coding c : cc.getCoding()) {
|
||||
if (c.hasSystem()) {
|
||||
String d = c.hasDisplay() ? " ("+c.getDisplay()+")" : "";
|
||||
if (c.hasCode()) {
|
||||
switch (c.getSystem()) {
|
||||
case "http://hl7.org/fhir/sid/cvx": return "CVX "+c.getCode()+d;
|
||||
case "http://snomed.info/sct": return "SCT "+c.getCode()+d;
|
||||
default:
|
||||
if (Utilities.startsWithInList(c.getSystem(), "http://terminology.hl7.org")) {
|
||||
return c.getCode();
|
||||
} else {
|
||||
throw new FHIRException("Unknown system "+c.getSystem());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Coding c : cc.getCoding()) {
|
||||
if (c.hasCode()) {
|
||||
return c.getCode();
|
||||
}
|
||||
}
|
||||
if (cc.hasText()) {
|
||||
return cc.getText();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void search(String[] p) {
|
||||
if (client == null) {
|
||||
throw new FHIRException("Not connected to to a server");
|
||||
}
|
||||
String search = "?name="+p[1];
|
||||
if (p.length > 2) {
|
||||
search = search +"&gender="+p[2];
|
||||
if (p.length > 3) {
|
||||
search = search +"&dob="+p[3];
|
||||
}
|
||||
}
|
||||
Bundle bnd = client.search("Patient", search);
|
||||
System.out.println(""+bnd.getTotal()+" Patients found. Printing "+bnd.getEntry().size());
|
||||
|
||||
for (BundleEntryComponent be : bnd.getEntry()) {
|
||||
Patient pat = (Patient) be.getResource();
|
||||
System.out.println(summary(pat));
|
||||
}
|
||||
}
|
||||
|
||||
private String name(Patient pat) {
|
||||
if (pat.getName().size() > 0) {
|
||||
return name(pat.getName().get(0));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String name(HumanName n) {
|
||||
if (n.hasText()) {
|
||||
return n.getText();
|
||||
}
|
||||
if (n.hasFamily()) {
|
||||
if (n.hasGiven()) {
|
||||
return n.getGiven().get(0)+" "+n.getFamily().toUpperCase();
|
||||
} else {
|
||||
return n.getFamily().toUpperCase();
|
||||
}
|
||||
}
|
||||
return "??";
|
||||
}
|
||||
|
||||
private void connectToServer(String url) throws URISyntaxException {
|
||||
client = new FHIRToolingClient(url, "FHIR-Command-Line-App");
|
||||
CapabilityStatement cs = client.getCapabilitiesStatementQuick();
|
||||
System.out.println("Connected to "+url+": "+cs.getSoftware().getName()+".");
|
||||
}
|
||||
|
||||
private void genMenu() {
|
||||
System.out.println("Simple Client. Commands you can run:");
|
||||
System.out.println(" c {url} - connect to a server");
|
||||
System.out.println(" s {name} [{gender}] {{dob]} - find a patient record");
|
||||
System.out.println(" p {id} - choose a patient record");
|
||||
System.out.println(" v [{field}] - see a set of field(s) in the current resource, or the whole resource");
|
||||
System.out.println(" e {field} {value} - edit a field in the current resource");
|
||||
System.out.println(" imm [{id}] - get a list of the patient's immunizations, or use the resource for the id (then use e to edit it)");
|
||||
System.out.println(" cnd [{id}] - get a list of the patient's conditions, or use the resource for the id (then use e to edit it)");
|
||||
System.out.println(" prc [{id}] - get a list of the patient's procedures, or use the resource for the id (then use e to edit it)");
|
||||
System.out.println(" ? - print this again");
|
||||
System.out.println(" x - exit");
|
||||
}
|
||||
}
|
|
@ -595,4 +595,23 @@ public class FHIRToolingClient {
|
|||
public void setLanguage(String lang) {
|
||||
this.acceptLang = lang;
|
||||
}
|
||||
|
||||
public Bundle search(String type, String criteria) {
|
||||
return fetchFeed(Utilities.pathURL(base, type+criteria));
|
||||
}
|
||||
|
||||
public <T extends Resource> T fetchResource(Class<T> resourceClass, String id) {
|
||||
org.hl7.fhir.r4.utils.client.network.ResourceRequest<Resource> result = null;
|
||||
try {
|
||||
result = client.issueGetResourceRequest(resourceAddress.resolveGetResource(resourceClass, id),
|
||||
getPreferredResourceFormat(), generateHeaders(), resourceClass.getName()+"/"+id, TIMEOUT_NORMAL);
|
||||
} catch (IOException e) {
|
||||
throw new FHIRException(e);
|
||||
}
|
||||
if (result.isUnsuccessfulRequest()) {
|
||||
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(),
|
||||
(OperationOutcome) result.getPayload());
|
||||
}
|
||||
return (T) result.getPayload();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,6 +91,10 @@ public class ResourceAddress {
|
|||
return baseServiceUri.resolve(nameForClassWithSlash(resourceClass) + "/" + opName);
|
||||
}
|
||||
|
||||
public <T extends Resource> URI resolveGetResource(Class<T> resourceClass, String id) {
|
||||
return baseServiceUri.resolve(nameForClassWithSlash(resourceClass) + "/" + id);
|
||||
}
|
||||
|
||||
public <T extends Resource> URI resolveOperationUri(Class<T> resourceClass, String opName,
|
||||
Map<String, String> parameters) {
|
||||
return appendHttpParameters(baseServiceUri.resolve(nameForClassWithSlash(resourceClass) + "$" + opName),
|
||||
|
|
|
@ -61,6 +61,7 @@ import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
|||
import org.hl7.fhir.r5.formats.FormatUtilities;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.model.DateTimeType;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.PropertyRepresentation;
|
||||
import org.hl7.fhir.r5.model.Enumeration;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
@ -421,7 +422,11 @@ public class XmlParser extends ParserBase {
|
|||
element.getChildren().add(n);
|
||||
} else {
|
||||
String npath = path+"/"+pathPrefix(child.getNamespaceURI())+child.getLocalName();
|
||||
Element n = new Element(child.getLocalName(), property).markLocation(line(child, false), col(child, false)).setFormat(FhirFormat.XML);
|
||||
String name = child.getLocalName();
|
||||
if (!property.isChoice() && !name.equals(property.getName())) {
|
||||
name = property.getName();
|
||||
}
|
||||
Element n = new Element(name, property).markLocation(line(child, false), col(child, false)).setFormat(FhirFormat.XML);
|
||||
if (property.isList()) {
|
||||
n.setPath(element.getPath()+"."+property.getName()+"["+repeatCount+"]");
|
||||
} else {
|
||||
|
@ -769,7 +774,11 @@ public class XmlParser extends ParserBase {
|
|||
}
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
xml.enter(element.getProperty().getXmlNamespace(),elementName);
|
||||
if (!xml.namespaceDefined(element.getProperty().getXmlNamespace())) {
|
||||
String abbrev = makeNamespaceAbbrev(element.getProperty(), xml);
|
||||
xml.namespace(element.getProperty().getXmlNamespace(), abbrev);
|
||||
}
|
||||
xml.enter(element.getProperty().getXmlNamespace(), elementName);
|
||||
if (!root && element.getSpecial() != null) {
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
|
@ -791,6 +800,37 @@ public class XmlParser extends ParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
private String makeNamespaceAbbrev(Property property, IXMLWriter xml) {
|
||||
// it's a cosmetic thing, but we're going to try to come up with a nice namespace
|
||||
|
||||
ElementDefinition ed = property.getDefinition();
|
||||
String ns = property.getXmlNamespace();
|
||||
String n = property.getXmlName();
|
||||
|
||||
String diff = property.getName().toLowerCase().replace(n.toLowerCase(), "");
|
||||
if (!Utilities.noString(diff) && diff.length() <= 5 && Utilities.isToken(diff) && !xml.abbreviationDefined(diff)) {
|
||||
return diff;
|
||||
}
|
||||
|
||||
int i = ns.length()-1;
|
||||
while (i > 0) {
|
||||
if (Character.isAlphabetic(ns.charAt(i)) || Character.isDigit(ns.charAt(i))) {
|
||||
i--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
String tail = ns.substring(i+1);
|
||||
if (!Utilities.noString(tail) && tail.length() <= 5 && Utilities.isToken(tail) && !xml.abbreviationDefined(tail)) {
|
||||
return tail;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (xml.abbreviationDefined("ns"+i)) {
|
||||
i++;
|
||||
}
|
||||
return "ns"+i;
|
||||
}
|
||||
private String checkHeader(List<ValidationMessage> errors, InputStream stream) throws IOException {
|
||||
try {
|
||||
// the stream will either start with the UTF-8 BOF or with <xml
|
||||
|
|
|
@ -1482,6 +1482,11 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
c.getPieces().add(gen.new Piece(null, translate("sd.table", "XML Namespace")+": ", null).addStyle("font-weight:bold"));
|
||||
c.getPieces().add(gen.new Piece(null, definition.getExtensionString(ToolingExtensions.EXT_XML_NAMESPACE), null));
|
||||
}
|
||||
if (root && ToolingExtensions.readBoolExtension(profile, ToolingExtensions.EXT_XML_NO_ORDER)) {
|
||||
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||
c.getPieces().add(gen.new Piece(null, translate("sd.table", "XML Order")+": ", null).addStyle("font-weight:bold"));
|
||||
c.getPieces().add(gen.new Piece(null, "The properties of this type can appear in any order in the XML", null));
|
||||
}
|
||||
if (definition.hasExtension(ToolingExtensions.EXT_JSON_EMPTY)) {
|
||||
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||
String code = ToolingExtensions.readStringExtension(definition, ToolingExtensions.EXT_JSON_EMPTY);
|
||||
|
@ -3755,7 +3760,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
}
|
||||
boolean no = root && ToolingExtensions.readBoolExtension(profile, ToolingExtensions.EXT_XML_NO_ORDER);
|
||||
if (no) {
|
||||
ret.tx("The children of this property can appear in any order in the XML.");
|
||||
ret.tx("The children of this type can appear in any order in the XML.");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -249,7 +249,7 @@ Validation_VAL_Profile_MultipleMatches_other = Found multiple matching profiles
|
|||
Validation_VAL_Profile_NoDefinition = No definition found for resource type ''{0}''
|
||||
Validation_VAL_Profile_NoMatch = Unable to find a match for the specified profile among choices: {0}
|
||||
Validation_VAL_Profile_NoSnapshot = StructureDefinition {0} has no snapshot - validation is against the snapshot, so it must be provided
|
||||
Validation_VAL_Profile_NoType = The type of element {0} is not known, which is invalid. Valid types at this point are {1}
|
||||
Validation_VAL_Profile_NoType = The type of element {0} is not known - it could not be determined from the information available. Valid types at this point are {1}
|
||||
Validation_VAL_Profile_NotAllowed = This element is not allowed by the profile {0}
|
||||
Validation_VAL_Profile_NotSlice = This element does not match any known slice {0} and slicing is CLOSED: {1}
|
||||
Validation_VAL_Profile_OutOfOrder = As specified by profile {0}, Element ''{1}'' is out of order (found after {2})
|
||||
|
|
|
@ -6215,12 +6215,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (ed.getRepresentation().isEmpty()) { // ignore xml attributes
|
||||
int count = 0;
|
||||
List<ElementDefinition> slices = null;
|
||||
if (ed.hasSlicing())
|
||||
if (ed.hasSlicing()) {
|
||||
slices = profileUtilities.getSliceList(profile, ed);
|
||||
for (ElementInfo ei : children)
|
||||
if (ei.definition == ed)
|
||||
}
|
||||
for (ElementInfo ei : children) {
|
||||
if (ei.definition == ed) {
|
||||
count++;
|
||||
else if (slices != null) {
|
||||
} else if (slices != null) {
|
||||
for (ElementDefinition sed : slices) {
|
||||
if (ei.definition == sed) {
|
||||
count++;
|
||||
|
@ -6228,6 +6229,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ed.getMin() > 0) {
|
||||
if (problematicPaths.contains(ed.getPath()))
|
||||
hintPlural(errors, NO_RULE_DATE, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), count, I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMIN, profile.getVersionedUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), Integer.toString(ed.getMin()));
|
||||
|
@ -6238,9 +6240,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
if (ed.hasMax() && !ed.getMax().equals("*")) {
|
||||
if (problematicPaths.contains(ed.getPath()))
|
||||
if (problematicPaths.contains(ed.getPath())) {
|
||||
hintPlural(errors, NO_RULE_DATE, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count <= Integer.parseInt(ed.getMax()), count, I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMAX, profile.getVersionedUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), ed.getMax());
|
||||
else if (count > Integer.parseInt(ed.getMax())) {
|
||||
} else if (count > Integer.parseInt(ed.getMax())) {
|
||||
ok = rulePlural(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), false, count, I18nConstants.VALIDATION_VAL_PROFILE_MAXIMUM, profile.getVersionedUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), ed.getMax(), Integer.toString(count)) && ok;
|
||||
}
|
||||
}
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -20,7 +20,7 @@
|
|||
<properties>
|
||||
<guava_version>32.0.1-jre</guava_version>
|
||||
<hapi_fhir_version>6.4.1</hapi_fhir_version>
|
||||
<validator_test_case_version>1.4.7</validator_test_case_version>
|
||||
<validator_test_case_version>1.4.8</validator_test_case_version>
|
||||
<jackson_version>2.15.2</jackson_version>
|
||||
<junit_jupiter_version>5.9.2</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
||||
|
|
Loading…
Reference in New Issue