Update XML Parser & logical model renderer for XML choice groups

This commit is contained in:
Grahame Grieve 2023-10-11 22:54:09 +08:00
parent 62835ff54d
commit e8a162cabb
3 changed files with 76 additions and 67 deletions

View File

@ -304,8 +304,10 @@ public class XmlParser extends ParserBase {
// this parsing routine retains the original order in a the XML file, to support validation
reapComments(node, element);
List<Property> properties = element.getProperty().getChildProperties(element.getName(), XMLUtil.getXsiType(node));
Property cgProp = getChoiceGroupProp(properties);
Property mtProp = cgProp == null ? null : getTextProp(cgProp.getChildProperties(null, null));
String text = XMLUtil.getDirectText(node).trim();
String text = mtProp == null ? XMLUtil.getDirectText(node).trim() : null;
int line = line(node, false);
int col = col(node, false);
if (!Utilities.noString(text)) {
@ -396,6 +398,7 @@ public class XmlParser extends ParserBase {
while (child != null) {
if (child.getNodeType() == Node.ELEMENT_NODE) {
Property property = getElementProp(properties, child.getLocalName(), child.getNamespaceURI());
if (property != null) {
if (property.getName().equals(lastName)) {
repeatCount++;
@ -462,9 +465,57 @@ public class XmlParser extends ParserBase {
}
}
} else {
if (cgProp != null) {
property = getElementProp(cgProp.getChildProperties(null, null), child.getLocalName(), child.getNamespaceURI());
if (property != null) {
if (cgProp.getName().equals(lastName)) {
repeatCount++;
} else {
lastName = cgProp.getName();
repeatCount = 0;
}
String npath = path+"/"+pathPrefix(cgProp.getXmlNamespace())+cgProp.getName();
String name = cgProp.getName();
Element cgn = new Element(cgProp.getName(), cgProp).setFormat(FhirFormat.XML);
cgn.setPath(element.getPath()+"."+cgProp.getName()+"["+repeatCount+"]");
element.getChildren().add(cgn);
npath = npath+"/"+pathPrefix(child.getNamespaceURI())+child.getLocalName();
name = child.getLocalName();
Element n = new Element(name, property).markLocation(line(child, false), col(child, false)).setFormat(FhirFormat.XML);
cgn.getChildren().add(n);
n.setPath(element.getPath()+"."+property.getName());
checkElement(errors, (org.w3c.dom.Element) child, npath, n.getProperty());
parseChildren(errors, npath, (org.w3c.dom.Element) child, n);
}
}
if (property == null) {
logError(errors, ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNDEFINED_ELEMENT_, child.getLocalName(), path), IssueSeverity.ERROR);
}
} else if (child.getNodeType() == Node.CDATA_SECTION_NODE){
}
} else if (child.getNodeType() == Node.TEXT_NODE && !Utilities.noString(child.getTextContent().trim()) && mtProp != null) {
if (cgProp.getName().equals(lastName)) {
repeatCount++;
} else {
lastName = cgProp.getName();
repeatCount = 0;
}
String npath = path+"/"+pathPrefix(cgProp.getXmlNamespace())+cgProp.getName();
String name = cgProp.getName();
Element cgn = new Element(cgProp.getName(), cgProp).setFormat(FhirFormat.XML);
cgn.setPath(element.getPath()+"."+cgProp.getName()+"["+repeatCount+"]");
element.getChildren().add(cgn);
npath = npath+"/text()";
name = mtProp.getName();
Element n = new Element(name, mtProp, mtProp.getType(), child.getTextContent().trim()).markLocation(line(child, false), col(child, false)).setFormat(FhirFormat.XML);
cgn.getChildren().add(n);
n.setPath(element.getPath()+"."+mtProp.getName());
} else if (child.getNodeType() == Node.CDATA_SECTION_NODE) {
logError(errors, ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.CDATA_IS_NOT_ALLOWED), IssueSeverity.ERROR);
} else if (!Utilities.existsInList(child.getNodeType(), 3, 8)) {
logError(errors, ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.NODE_TYPE__IS_NOT_ALLOWED, Integer.toString(child.getNodeType())), IssueSeverity.ERROR);
@ -473,6 +524,15 @@ public class XmlParser extends ParserBase {
}
}
private Property getChoiceGroupProp(List<Property> properties) {
for (Property p : properties) {
if (p.getDefinition().hasExtension(ToolingExtensions.EXT_ID_CHOICE_GROUP)) {
return p;
}
}
return null;
}
private boolean validAttrValue(String value) {
if (version == null) {
return true;
@ -515,6 +575,8 @@ public class XmlParser extends ParserBase {
return p;
}
}
return null;
}

View File

@ -95,69 +95,6 @@ import org.hl7.fhir.utilities.xhtml.XhtmlParser;
public class StructureDefinitionRenderer extends ResourceRenderer {
// public class ObligationWrapper {
//
// private Extension ext;
//
// public ObligationWrapper(Extension ext) {
// this.ext = ext;
// }
//
// public boolean hasActor() {
// return ext.hasExtension("actor");
// }
//
// public boolean hasActor(String id) {
// return ext.hasExtension("actor") && id.equals(ext.getExtensionByUrl("actor").getValue().primitiveValue());
// }
//
// public Coding getCode() {
// Extension code = ext.getExtensionByUrl("obligation");
// if (code != null && code.hasValueCoding()) {
// return code.getValueCoding();
// }
// if (code != null && code.hasValueCodeType()) {
// return new Coding().setSystem("http://hl7.org/fhir/tools/CodeSystem/obligation").setCode(code.getValueCodeType().primitiveValue());
// }
// return null;
// }
//
// public boolean hasFilter() {
// return ext.hasExtension("filter");
// }
//
// public String getFilter() {
// Extension code = ext.getExtensionByUrl("filter");
// if (code != null && code.getValue() != null) {
// return code.getValue().primitiveValue();
// }
// return null;
// }
//
// public boolean hasUsage() {
// return ext.hasExtension("usage");
// }
//
// public String getFilterDocumentation() {
// Extension code = ext.getExtensionByUrl("filter-desc");
// if (code != null && code.getValue() != null) {
// return code.getValue().primitiveValue();
// }
// return null;
// }
//
// public List<UsageContext> getUsage() {
// List<UsageContext> usage = new ArrayList<>();
// for (Extension u : ext.getExtensionsByUrl("usage" )) {
// if (u.hasValueUsageContext()) {
// usage.add(u.getValueUsageContext());
// }
// }
// return usage;
// }
//
// }
public class SourcedElementDefinition {
private StructureDefinition profile;
private ElementDefinition definition;
@ -1473,6 +1410,11 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
c.getPieces().add(gen.new Piece(null, "An ID is not allowed in this context", null));
}
}
if (definition.hasExtension(ToolingExtensions.EXT_ID_CHOICE_GROUP)) {
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
c.getPieces().add(gen.new Piece(null, translate("sd.table", "Choice Group")+": ", null).addStyle("font-weight:bold"));
c.getPieces().add(gen.new Piece(null, "This is a repeating choice group that does not appear directly in the instance", null));
}
if (definition.hasExtension(ToolingExtensions.EXT_XML_NAME)) {
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
if (definition.hasExtension(ToolingExtensions.EXT_XML_NAMESPACE)) {
@ -3663,6 +3605,11 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
tableRow(tbl, "ID Expectation", null, strikethrough, "An ID is not allowed in this context");
}
}
if (d.hasExtension(ToolingExtensions.EXT_ID_CHOICE_GROUP)) {
tableRow(tbl, "Choice Group", null, strikethrough, "This is a repeating choice group that does not appear directly in the instance");
}
// tooling extensions for formats
if (ToolingExtensions.hasExtensions(d, ToolingExtensions.EXT_JSON_EMPTY, ToolingExtensions.EXT_JSON_PROP_KEY, ToolingExtensions.EXT_JSON_NULLABLE,
ToolingExtensions.EXT_JSON_NAME, ToolingExtensions.EXT_JSON_PRIMITIVE_CHOICE)) {

View File

@ -255,7 +255,7 @@ public class ToolingExtensions {
public static final String EXT_OBLIGATION_TOOLS = "http://hl7.org/fhir/tools/StructureDefinition/obligation";
public static final String EXT_OBLIGATION_CORE = "http://hl7.org/fhir/StructureDefinition/obligation";
public static final String EXT_NO_BINDING = "http://hl7.org/fhir/tools/StructureDefinition/no-binding";
;
public static final String EXT_ID_CHOICE_GROUP = "http://hl7.org/fhir/tools/StructureDefinition/xml-choice-group";
// specific extension helpers